OEL Introduction

Outlook Extensions Library

TeamScope Software, Inc.

http://www.teamscope.com

mailto:info@teamscope.com

Microsoft Outlook is a very functional development platform for simple e-form based applications. Some significant effort can be required, however, to develop more advanced Outlook applications. This object library contains a feature set that is designed to ease this effort. The library fully leverages the native Outlook interface environment to provide needed productivity enhancements for the developer.

The Outlook Extensions Library (commonly referred to in this document as OEL) is packaged as a 32-bit ActiveX dynamic link library (DLL). Its properties and methods are set and called from inside your Outlook forms, using its native VBScript language.

For a quick look at what a OEL form might look like, take a look at an example screen which shows you some of the capabilities. Please review the basic folder setup and important form setup notes information before adding these new features to your Outlook forms.

The Outlook Extension Library provides the following types of capabilities:

  • Change History

Automatically track changes to selected field values

  • Linking to other items

In one click automatically jump to a folder and select an item

  • Configuration Data

Store and make use of database "like" information for a variety of purposes

  • VB Script Support

Set of basic functions that are provided to give VB Script more capability

  • URL based functions

Functions that allow for user friendly text path strings instead of GUIDs

  • Form support

WYSIWYG Printing, Position and Size control, Correct home folder etc.

  • Fields support

Support for protecting data at the field level and form safe field value queries

  • Events & tracing

Tracing data change events and controlling errors

  • Item Locking

Prevent users form updating the same item and causing collisions

  • Additional controls

Full function Grid and Calendar controls allow you forms unlimited functionality

  • Workflow

OEL provides the foundation for a powerful work flow system

If you used the pervious version of OEL you may want to review the What's New section.

Copyright:

The Outlook Extensions Library is copyrighted Ó1999-2001 by TeamScope Software, Inc. The information in this document cannot be reproduced or transmitted, for any purpose, without the express written permission of TeamScope Software, Inc.

Trademarks:

TeamWork™ is a trademark of TeamScope software.

Disclaimer:

Please review the disclaimer in the appendix of this document which discusses certain limitations and legal responsibilities

Rev 2.5b Jan 9 2001


What's New

What's New in Outlook Extensions Library Version 2.5

For more details of on changes in previous releases please review the revision history.

New!

On-Line help! No more DOC files! (This replaces the "OEL Developer's Guide)

Item Sync Object Provides a method to automatically copy items to users' private folders

ItemProperties Allows a simplified way of accessing fields without one-offing your forms

UpdateLinks Update the contact links collection removing broken links and fixing the display names

GetItemFromURL Will return a item from a Outlook URL

GetFolderFromURL Will return a folder from a Outlook URL

SortArray Sorting arrays

MsgDataValidate Allows a combo box to validate the entry and automatically add it to the list through a dialog

CopyGridProperties A convenient function to copy grid control properties for help with printing

CurrentItem For external processes or earlier versions of Outlook to specify the current item

Replace For users of VBScript prior to version 5

Examples Fragments of code you can use to add functionality to your forms

Improved!

GenRefID New sequence number capabilities

ExitState New Item_Close functionality... no more annoying "Do you want to save changes" dialogs

WriteToField New "AppendOnTop" parameter allow you to specify the way the changes are appended to the history log

Display GetItems.Display now has new delay parameter so it will work with opening up custom forms

ReadMsgEntryVar Now supports redirection to individual elements of a Grid (Keyword array)

ArrayToText Now support line wrapping columns

CreateObject Calling OEL from unmodified 1st page forms.

Fixed:

One-Off forms Forms no longer one-off which means that your items are up to 100x smaller and run faster!

AddMsgSection Fixed message cache update error

OnLine Now can correctly report for non-English systems


Interface

Architecture

The Outlook Extensions Library (OEL) is a 32-bit Active X DLL that resides on each client. OEL provides a number of high-level groupware functions that your application can use directly. OEL also includes some Outlook form controls (OCX) that provide allow you to enhance the UI capabilities of your applications. OEL allows your applications to take better advantage of all of the functionality and flexibility of Outlook along with the power and scalability of Exchange.


Basic Folder Setup

Basic Application Folder Setup

To take full advantage of OEL, applications should be deployed in folders structures as shown below. OEL can be used in a Outlook Private Folders (PST file) but to allow multi-user applications you will need to use Exchange Public Folders. Each application that performs a specific function is typically stored in a separate set of folders as shown below.

The top level Application Folder contains your actual items that your users will be creating. When you create this folder, make sure you define it to contain the same base type of workflow form you are developing (Task, Contact, etc.).

The Configuration folder is a folder, or Public Folder, that holds all of the applications configuration information. Typically this folder is used to hold other supporting configuration data messages. This folder must always be defined as type "Mail Items", and it must be a child of the Application Folder.

The Form Design folder is where you save the Outlook form that serves as the “master form” (i.e. the design template for your workflow form). This folder must be of the same base type as the top level Application Folder. Please see the appendix for additional information on publishing.

The Locks folder will be used if you utilize record-level locking in your workflow form. This folder is optional but is recommended.

Note:

All applications using OEL in Exchange Public Folders can be also be used while running off-line by using folder synchronization. For more information on this please review the Off-line and Distributed operation notes.


Referencing the Library

Form Setup Notes

This document assumes that you have some experience in developing custom Outlook forms. We have provided some additional information on some Outlook forms issues that may help out. If you need additional help getting started you can contact Support@TeamScope.com for assistance.

Referencing the library: (Getting In)

Before you can use any of the methods or properties of the OEL, you must first create a reference to the OEL object. This is done with VBScript in your forms Item_Open event, using Outlook's "CreateObject" method.

Set oLib = Application.CreateObject("OutlookExtensions.Library")

oLib: (object) Returned reference to the extensions object library

Call during: should be set as soon as possible in the Item_Open event.
Note: Do not reference the library in the Item_Read event.

Note: Throughout this document, we use the variable oLib to refer to the OEL object. Of course, you can use any variable name you choose in your forms code.

Notes:

  • The "Set" before the object is absolutely necessary because this is an object reference.

  • The library holds on to the context of the current message and folder for later use. In this way, you don't have to pass the context reference constantly.

  • For OL97 and OL98 if the first visible form page is not modified in some way you must call the CurrentItem immediately after making this reference.

  • When the object is first instantiated, there can be an initial delay. Subsequent calls are much faster.

  • Occasionally after installing OEL for the first time you will get an error stating that the library could not be referenced but will proceed to operate. This error will go away after you restart your computer.

  • As with any ActiveX object, the object must be registered on your system. See the Setup Files section in the Appendix for more details.

  • The library operates with all versions of Outlook (OL97, OL98 and OL2000).

The Item_Open code example below demonstrates the proper way to create a reference to the library. This example handles both situations where the library DLL may be missing or is out of date; in both cases, the NewLibraryNeeded subroutine is called. This subroutine provides a simple way to notify the user of the problem, and it provides a link to a support information folder that can include a Setup program the user can run to install a current version of the OEL.

Function Item_Open()

  On Error Resume Next             ' To cause the call to NewLibraryNeeded if any errors

  Set oLib = Application.CreateObject("OutlookExtensions.Library")

  If oLib.Version < 020501 then    ' In case the library is out of date:  v2.5.1

       Call NewLibraryNeeded

       Exit Function               ' Prevent any further processing which will just cause more errors

  End If

  On Error Goto 0                  ' Turn the error handler back on

  oLib.History.Setup "Subject; Body; Categories"

... your code follows ...

End Function

Sub NewLibraryNeeded()

  On Error Goto 0

  Set oNotice=Application.CreateItem(0)

  oNotice.Subject="Error: Outlook Extensions Library is missing or is out of date"

  t="An error occurred during referencing the Outlook Extensions Library."+vbCR

  t=t+"You need to have a new version of the library installed on your machine."+vbCR

  t=t+"You can install the library yourself by clicking on the following link:"+vbCR

  t=t+"<Outlook:\\InformationStore\folder\folder\~Extensions Library Support>"+vbCR+vbCR

  oNotice.Body=t+"Thank You."

  oNotice.Display

End Sub

Exiting your Outlook form: (Getting Out)

Exiting an Outlook form can be done from either the "Save and Close" button (assuming an IPM.Task form type), from the form windows "X" Close box, or via the Escape ("Esc") key. The "Save and Close" button calls the Item_Write event first if the form needs to be saved because a field has changed. The "X" and "Esc" methods call the Item_Close event first.

Various factors need to be considered during the Item_Write event:

  • Avoiding unnecessary changes
    Many OEL functions make use of callbacks and other features that potentially cause "unintentional" updating of fields. To avoid these erroneous updates, use the provided library Change History to track only fields that are of true value to the form. Only changes to these "important" fields will then cause the form to be saved.

  • Other processes
    When an external process (such as the TeamWork    Ô Workflow Agent) accesses an item using the OEL, the Item_Read event occurs but not the Item_Open event; therefore, the OEL object is not initialized. If the external process then updates the item, the Item_Write event fires. You must therefore include script code in the Item_Write event that bypasses any references to the OEL, since in this case it will not be a valid object. The "IsObject(oLib)" statement is sufficient to determine whether the item's Open event was called and thus whether a valid reference to the OEL exists.

  • Canceling
    For various reasons the library may need to cancel the users attempt to save the form. This is typically done for data validation reasons.

The script code provided below should be included in any Outlook form that makes use of the Extensions Library.

Function Item_Close()

If oLib.ExitState<0 Then ' Check if user has pressed 'X' or 'Esc'

oLib.ExitState=-1 ' Tell Item Write that you want to cancel

Call Item_Write

End If

End Function

Function Item_Write()

If IsObject(oLib) Then        ' Check to make sure the item was opened by a user (Item_Open event)

  '*** do updating of any unbound fields here ***

oLib.History.Process "TheNameOfYourHistoryField"

oLib.Workflow.Process       ' Optional: Only if you are using the TeamWork workflow product

oLib.CheckLock              ' Optional: Only if you are using item locking

If oLib.ExitState>0 Then

Item_Write=True       ' complete the write event saving the item

Else

Item_Write=False      ' cancel the write event

If oLib.ExitState<>-2 Then  ' Close was not canceled by validation (-2)

Item.Close(1)         ' olDiscard - avoid Outlook "Save" message

End If

End If

End If

End Function

Outlook 97 Note:

Canceling the Close event from the Write event does not work if it was is initially called from the Close event in Outlook 97. If you use the Item_Write code as above you will get the error shown below in Outlook 97. This error does not actually cause any problems but can be very alarming to your users. If this message is problematic and you want the old 'Do you want to save changes" one instead then simply remove the Item_Close code as shown above.

One solution for OL97 users is to just train users to always press the "Save and Close" button because if the ExitState says that actually nothing changes (ExitState=0) then the item will not be saved any ways.


Data types & Parameters

Data Types and Parameters

Parameters

All OEL parameters are strings, represented in VB Script as variants, unless otherwise indicated in the reference guide. This means that if a parameter is not a variable, it must be enclosed with quotes " ". In this help document all string parameters are assumed by default. Parameters that are other than strings will be indicated so.

In VB Script all variables are variants.

Example: Both vString and vNumber are both still the same variant data type.

vString="Hello"

vNumber=10

Arrays

In VBScript, always specify (Dim) array variables as Variant types, which is the default. Variants can automatically convert to contain arrays of one or more dimensions. Important: Do not "Dim" these variables as arrays, because arrays cannot be passed as function returns. Do not do: Dim vMyValue( )

All array operations are zero (0) based unless otherwise noted. Use the VB Script "UBound" function to determine the length and dimensions of the returned array.

Notes on Keywords fields

An Outlook Keywords field is a single field that contains an array of Variant items. Keywords fields provide a very convenient place to store array information, and they allow the ability to perform multi-categorized views in the Outlook Explorer.

The Outlook "Categories" field is probably the most common Keywords field. Ironically, in VBScript the Outlook "Categories" field behaves entirely differently from any other user-defined Keywords field. The Outlook "Categories" Keywords field behaves as a comma-delimited text field, while all user-defined Keywords fields are Variant arrays.

VB Script cannot read array values from Keywords fields. The Extensions Library therefore has routines that allow you to easily perform operations on both types of these Keywords field behaviors, as illustrated in the following examples.

To make the Outlook "Categories" field behave like an array:

Array = oLib.Support.TextToArray(Item.Categories,",")

To make an array Keywords field behave like the "Categories" field:

Text = oLib.Support.ArrayToText(Item.UserProperties("MyKeywordsField"),",")

Initial Values

For every field you can specify the default value at design time. Typically you want to set the value to "" as shown below. This is actually very important and a good habit to get into for all fields. Having erroneous values in your fields can potentially lead to all kinds of confusion. For custom fields this has even more importance since if a custom field does not have any value defined then it is not instanced along with the item when the item is created.


Callback Events & Tracing

Callback Events and Tracing

Library Callbacks

Certain library functions require the use of a callback. A callback is used when your Outlook code initiates another process, and that process at some point needs to signal (call back) Outlook that the process has information for Outlook to process. This functionality is required in order to allow Outlook to continue operating without freezing while the other process completes. This callback functionality provides a basic form of event processing in Outlook.

There are a couple of functions in OEL that make specific use of callbacks.

  • Event Timer

  • GetItems.Display

  • Grid Control

  • Agent Scripting (TeamWork™ only)

The OEL callback functions use Outlook's CustomPropertyChange or PropertyChange event, depending on whether the callback field is custom or is native to Outlook. Each callback function uses a separate defined field.

The following example illustrates the method for processing callback field events within your form:

Sub Item_CustomPropertyChange(ByVal PropName)

Select Case PropName

Case "CallBackField1"

Process information for callback 1

Case "CallBackField2"

Process information for callback 2

End Select

End Sub

Data / Event Tracing

Besides other processes calling Outlook as described above, all variables that change in a Outlook form cause the property change events in the Outlook form to fire. These property change events are the primary means in which Outlook forms communicate data activity that can be acted upon. OEL has a very convenient tool that can be used in the property change events to preform a trace. This data value tracing can be very useful when trying to debug forms that are firing lots or events or have data values that are changing rapidly.

GetPropertyValue

The GetPropertyValue method is for use in the Item_CustomPropertyChange and Item_PropertyChange events. In these events, Outlook provides the name of the changed property, but not its value. Getting the value from the name may seem like an easy task, using the Item.UserProperties property; however, complexities arise when the value is an array, is empty, or has one or more embedded delimiters (such as "|", as will be the case from the OlGrid callbacks). The GetPropertyValue method also is the vehicle for event tracing as described next .

Sub Item_CustomPropertyChange(ByVal PropName)

On Error Resume Next ' required for pre Item_Open events

PropVal=oLib.GetPropertyValue(PropName)

Select Case PropName

Case "Prop1"

Process information for callback 1

Case "Prop2"

Process information for callback 2

End Select

End Sub

TraceOn & TraceOff functions

The TraceOn and TraceOff functions are used to trace data changes in the Item_CustomPropertyChange and Item_PropertyChange events. This tracing (logging) capability is in many cases a favorable alternative to using a simple MsgBox function or even the Outlook Script Debugger. The MsgBox function and Script Debugger are sometimes difficult to use because of the number of spurious events generated, and also the fact that the display of a dialog sometimes disrupts the normal event pattern, which can lead to erroneous results. This tracing actually takes place inside of the GetPropertyValue function as described above and thus this function must be present in the property change events to operate.

As shown in the example below some form operations, such as the Grid for example, will generate a number of data change events.

Example Trace Output:

Sep 16 2000> ###### Starting Outlook Extensions Library Property Trace ######

13:17:51> Sub Region: Uruguay

13:18:09> PartID: 000000006AB806A1A00AD41196860080C88C020124322000

13:18:12> GridCallback: BeforeUserResize,-1,7,False|9/16/2000 1:18:12 PM

13:18:15> GridCallback: BeforeEdit,4,6,False|9/16/2000 1:18:15 PM

13:18:15> GridCallback: MouseDown,1,0,7230,1305|9/16/2000 1:18:15 PM

13:18:15> GridCallback: MouseUp,1,0,7230,1305|9/16/2000 1:18:15 PM

13:18:15> GridCallback: Click|9/16/2000 1:18:15 PM

13:18:16> GridCallback: DblClick|9/16/2000 1:18:16 PM

13:18:18> GridCallback: BeforeEdit,4,6,False|9/16/2000 1:18:18 PM

13:18:20> GridCallback: KeyDown,50,0|9/16/2000 1:18:20 PM

13:18:20> GridCallback: KeyPress,50|9/16/2000 1:18:20 PM

13:18:20> GridCallback: BeforeEdit,4,6,False|9/16/2000 1:18:20 PM

13:18:20> GridCallback: StartEdit,4,6,False|9/16/2000 1:18:20 PM

13:18:21> GridCallback: ChangeEdit|9/16/2000 1:18:21 PM

13:18:22> GridCallback: ValidateEdit,4,6,False|9/16/2000 1:18:22 PM

13:18:22> GridCallback: AfterEdit,4,6|9/16/2000 1:18:22 PM

13:18:22> GridCallback: BeforeEdit,3,7,False|9/16/2000 1:18:22 PM

13:18:22> GridCallback: MouseUp,1,0,7680,1110|9/16/2000 1:18:22 PM

13:18:22> GridCallback: Click|9/16/2000 1:18:22 PM

13:18:24> GridData: 1; 000000001A44200000002ABD40000F45AB730950AD0002C4520000; ....

13:18:24> Secure Access Data: Ù[þFBÿlÐ

13:18:24> History: <cr>------------- Workflow Agent on 10/30/1999 12:10:58 PM ------ ....


Change History

The Change History functions provide easy-to-use end to end tracking of changes of data fields in a form. With two simple calls, one in the Item_Open event and one in the Item_Write event, your form has full change tracking capabilities covering who changed what data, when and by whom the change was made. The change history functions supports a number of different field data formats such as the Notes (body) and multi-valued Categories fields.

Item_Open event: Setup

Item_Write event: Process

Provide access to original values GetInitialValue

These functions also play an important role in determining the status (ExitState) of a form, restoring initial values (MsgDataValidate) and a provide a data field list for the Workflow Analyzer.

Below is a screen example of what the change history would look like. In Outlook it is simply a text box with the multi-line property set to true. You should also set the ReadOnly property of this field to true.


Item Linking

Linking to other items in other folders

In Outlook, like the Web, linking to other objects is an important feature. Currently, in order to link to other items, Outlook users are limited to the "Insert Item..." interface. This "Insert Item" function is very difficult for the user involving many clicks, and does not allow direct programmatic access to the returned item.

The Extensions Library provides the ability to programmatically control the linking of items from other folders, by allowing your form to display a folder in its native view and receive the item(s) clicked on by the user. This provides a powerful user interface that gives Outlook linking abilities similar to those found in database products.

Programmatically the process is very straightforward as illustrated below.

1) Call the GetItem.Display with a path to the desired folder and a callback field name from a button click or other event.

Sub cmdSomeButton_Click( )

oLib.GetItems.Display "\Contacts\Customers", "CustomerID"

End Sub

2) The target folder is displayed and the user selects one or more items by double clicking on them.

3) For each item the user selects a callback is generated with the EntryID of the selected item

Sub Item_CustomPropertyChange(ByVal PropName)

On Error Resume Next

PropVal=oLib.GetPropertyValue(PropName)

Select Case PropName

Case "CustomerID"

Set oCustomer=oNameSpace.GetItemFromID(PropVal,oFolder.StoreID)

Item.Links.Add oCustomer ' add the customer to the links collection - OL2000 only

End Select

End Sub


Configuration Data

Configuration Data Items

Database records:

The most obvious way to connect to data sources is to use a database connection. In some situations this is a completely viable solution. However, this has many potential drawbacks in Outlook:

  • Requires a separate system to be developed and maintained

  • Connection overhead will slow down forms

  • Will not work off-line in Outlook

Individual item records:

Another way to store information is to store data records in individual Outlook message items and fields. This approach directly parallels records in a database table. Unfortunately this has several issues:

  • Limited available tools for accessing the data ... basically just Items.Restrict("some filter") and lots of coding

  • Maintaining data records as individual items is difficult and has massive overhead

  • Performance is not acceptable for most situations.

Item data text records:

The best way to provide efficient and simple configuration information in Outlook is to store the values in keyed (tokenized) message bodies. The format of the messages is a similar "Section - Key" format as is used in Windows INI files. (Think XML light)

This approach to storing "structured" text data proves to be highly effective in practice.

  • Each message data item can effectively store thousands of data points with very little overhead.

  • You can employ the use of multiple message data files in one message to further boost performance

  • With a small amount of script programming you can provide table and join functionality similar to that of a database.

  • You can stay inside of Outlook and leverage its features like the ability to work off-line

OEL support:

To facilitate this data storage technique OEL provides a whole set of functions to make development easy. These functions provide you with a single line of code high speed access to every aspect of your data.

  • SetFolder Define the data folder location

  • ReadMsgData Load into a array a whole list of data records

  • ReadMsgEntry Read a single record key

  • ReadMsgEntryVar Read a single record using variable redirection back to the current item

  • ReadMsgSection Load into an array a section of data and associated keys

  • ReadMsgSectionList Determine how many separate data sections are available in an item

  • AddMsgSection Add a new set of data records

  • DeleteMsgSection Remove a set of data records

  • MsgEntry Update the value of a data record

  • MsgDataValidate Provide a list validation and automatic record addition

To improve performance, anytime these data items are used, their data is automatically cached. By making use of multiple data sections in a single message you can achieve extremely good performance with very low overhead.

In addition OEL includes a Publisher tool that provides an automatic system for linking these data message items to any ODBC data source for automatic update synchronization at user-defined intervals. This means that you can have these message data items automatically populated from existing legacy database systems.


VB Scrip Support

VB Script Support

The purpose of this class of functions is to provide function that are not available in VB Script but necessary in many applications.

ClipboardText VB GetText and SetText functions

FormatString VB Format function

BeepTone VB Beep function

TextToArray Converts delimited text to multi-dimensioned arrays.

ArrayToText Converts arrays to delimited text. Gets past the VB Script error which can't read keyword arrays

RunShell Allows ability to launch application files and open web URLs

SortArray Simple sorting

Replace Earlier versions of VB Script do not have this useful function

TimerField Specify a timer to generate a callback interrupt which allows Outlook to continue without freezing

TimerInterval Specify the timer interval


URL Based Functions

URLs play an important role in Outlook

  • Provide an ability to link to items

  • Will work in any Outlook body field

  • Will work with all version of Outlook

Unfortunately MS provides no support for them programmatically. By using text URLs instead of GUIDs your code is easier to read and manage.

Create a absolute URL from either a Folder or Item

GetURL

These two function return Folder or Item objects from a URL

GetFolderFromURL Return a folder from a Outlook URL

GetItemFromURL Return an item from a Outlook URL

On very important thing about using item URLs is that the subject must be unique within a folder. This GenRefID function will help you to do that.

GenRefID Generate a unique subject reference ID


Form Support

OEL provides a number of functions to help you with Outlook forms.

Printing

As you probably know, there is no way to print a Outlook form. This is a major omission by MS. This FormPrint function provides a true high quality WYSIWYG form printing solution.

FormPrint

CopyGridProperties

Form positioning

Under normal Outlook behavior, an Outlook form remembers the size of the previous form. This can be less than optimal for custom forms that are designed to a specific size. These methods allow for specific and consistent control over the position and size of your custom Outlook form.

SetFormSize

SetFormPos

Other Misc:

There are a number of other functions that a very useful:

HomeFolder Know the true folder of your form... important when linking from other folders!

OnLine Know whether you are running on or off line

DisplayErrors OEL supports two modes of error handling

OutlookVersion Know which version of Outlook you are running


Fields Support

Accessing built-in fields:

In Outlook fields are accessed using Outlook Item.UserProperties method. This function works fine for accessing user defined fields. Accessing built-in field is normally accomplished by directly accessing the property. Example: Item.DueDate Accessing built-in field via a string will cause the form to become one-offed due to a bug in Outlook. For Example: Item.UserProperties("DueDate",False) Also, there are some other property inconsistencies that are addressed. The OEL ItemProperties function provides a solution to these shortcomings. OEL itself uses this function in many places such as the History, GetPropertyValue, ReadMsgEntryVar functions and various Workflow operations.

Encrypting information

In Exchange security is only available at the folder level. This means that you can't specify that certain users have access to certain fields or records. These library methods allow for encryption and decryption of specific data. You can use them to protect selected fields of data in a folder, so that only an appropriate subset of users can see the unencrypted data.

The security access to these fields is controls by a list of authorized users that is specified in a different folder. The security of the configuration folder is set at a higher level than that of the application folder. This access list is simply the E-mail display addresses of the people, or DL, who can have access to view the decrypted data. If the current user is not listed on the CryptoAccess key, the functions will just return "**********"

Support for these encryption functions are built into the TeamWork product. If you want use these encryption function in a non-TeamWork application you will need to create a post item in the configuration folder called "Workflow Configuration" and enter data in the body as shown below.

[SetupInfo]

CryptoAccessResolved= User1; User2; User3

Note that you must use fully resolved display names in this CryptoAccessResolved list. Distribution lists cannot be used in this entry, you just resolve the individual user accounts out individually. These entries must be the E-mail display name exactly as they appear in the display line of an E-mail after it has fully resolved.

See: Encrypt, Decrypt

Security Precautions:

To make sure the security cannot be bypassed you must apply the following precautions. It is the responsibility of the designer of the form to ensure that the appropriate encrypted fields are read from and written to using these encryption functions. Failure to follow these points will potentially result in unsecure data. (Please note that we do not specify or guarantee the "strength" of encryption provided with these functions.)

1) The folder with the CryptoAccessResolved user entry list must be protected from unauthorized changes by using standard Exchange folder security.

2) The folder containing the encrypted items must have the "delete" (and thus also move) permission turned off and ownership limited to basically the same users as those specified in the CryptoAccess field.

3) The field that is used to display the unencrypted (clear text) data must not be bound to a field. (See notes below)

Field Binding notes:

It is important to understand and follow which fields and controls are bound and unbound when using the Crypto functions.

1) The field containing the encrypted (secure) data must be physically on the form and bound to a textbox control. You should hide this control behind another control so as to not confuse the user.

2) The control displaying the clear text (unsecure) data must not be bound to any field!

Important Note:

Copying items with encrypted data to other folders will just further scramble the encrypted data. Please understand this fact it may limit your application of this function.


Item Locking

Locking items to protect from multiple edits

These methods allow protection from multiple users attempting to update the same item simultaneously. Without this capability, Outlook/Exchange allows for multiple users to simultaneously update the same item, which then generates conflicts. To provide locking, OEL automatically generates a special lock reference item in a separate "Locks" folder. Although this is more complex and does involve additional overhead than simply updating a field on the item, it has several big advantages.

  • Simply reading an item does not update it, forcing it to generate a Write event.

  • If a user cancels an update to an item, the lock is automatically removed.

  • Locks can be revoked by another process, allowing the item to be captured without a conflict being generated.

See: SetLock, LockState, CheckLock

Prevent this dreaded screen!

These methods also provide notification of who has the item open, and when it was opened.

Locking Example:

Function Item_Open()

Set oLib = Application.CreateObject("OutlookExtensions.Library")

oLib.Config.SetFolder ""      ' use the current Folder

oLib.SetLock "Locks"

If oLib.LockState<>"" Then Msgbox oLib.LockState

End Function

Function Item_Write()

oLib.CheckLock                ' Check the lock just before saving

If oLib.LockState="" Then     ' or you can check for ExitState=0

Item_Write=True         ' Lock is still valid

Else

Msgbox oLib.LockState   ' Inform the user

Item_Write=False        ' Cancel the update

Item.Close(1)           ' olDiscard - avoid "Save" message

End If

End Function


Item Sync

Public folders are, without question, the place to store information to be shared by teams of users. However, there are situations in which it is beneficial to have Public Folder items be mirrored (synchronized) to one or more users' private mailboxes. A common example would be if you have a Public Folder of company events, but want some of the items to be automatically copied to the users' private calendars.

This OEL function can be added to any Appointment or Task item in a public folder with just a few lines of code. (The UI display control shown below is actually optional) You can specify in your code a list of users to receive copies of items, or the user list can be specified from a published list.

See: Setup, Process, Remove, Examples

User Interface:

A user interface as shown above is optional but certainly recommended. With this interface, you can control the publishing process.

User Name: The possible recipients who will be receiving the copies in their private folder

Pub: Check off the recipients you want

Status: The status of the last publishing operation

Publish: You don't actually need this command button because you should call it in the Item_Write event to make sure it is called automatically when anything changes on the form.

Force: The optional "Force" check box will automatically recreate the item for any selected user who deleted it.

Notes:

Only some items are currently supported: Appointments and Tasks. Custom forms being sent to the recipients are not supported.

All synchronized items are placed into users' private folders in the defined default locations

Operational Modes:

There are two modes in which the feature can operation: User and Agent.

In user mode this function requires delegate access for all users involved (See below). When using the workflow agent users only need to delegate to the one workflow agent mailbox account.

Delegate Access: (User Mode)

In order to use the Item Sync functions you must assign delegate access to others users that will be pushing an item into your private folders. This dialog is accessed from the <Tools><Options> menu when connected to an Exchange server. The example below would be the required delegates for User A for the example shown above.

Agent Mode:

For large organizations having users assign delegate access to all other potential users is not a practical solution for two reasons.

  • Users may not trust other users to be looking into their private folders

  • Its just impractical to list and keep updated all the users

To solve this you can make use of the TeamWork™ workflow agent. When using the workflow agent users only need to delegate to the workflow agent account. Because the workflow agent only writes updates and has no ability to transfer private information to other users, your users should be allowed to trust it as a delegate.


Controls

ActiveX Controls

Without certain controls you cannot make full featured Outlook forms. For the most part, Outlook comes with many controls. However, Outlook is missing two important controls: a full featured editable Grid and a calendar control that you use in your custom forms. OEL provides these two controls.

The Grid: (OlGrid2.OCX)

The OlGrid control is actually a OEM version of Video Soft's VS Flex grid control that has been specially modified for use in Outlook. If you have tried to use the list control with multiple columns your struggles are over; OlGrid is a full-featured no compromise Grid control.

See: OlGrid

The Calendar: (OlCal2.OCX)

The point of the OlCal control is to look and function identical to the one that MS uses.

See: OlCal


OEL Example Screen

Example Screen

Please note that this is just an example screen that is showing you some of the many features of the Outlook Extensions Library. This form is just to showcase the features and controls and is not intended to make any business sense but it should give you an idea of what can easily be built. This demo form is available in the OEL Outlook PST file under the Demo folder.


CheckLock

Check to see if the lock that was originally granted is still valid

oLib.CheckLock

Called during: Item_Write event, just before final ExitState check is done

Sets: LockState property:
a) "" if lock is still ok (has not been revoked)
b) "Error: Lock has been revoked. Changes will not be saved." if the lock has been revoked.

ExitState property:

If the lock is unavailable, then the ExitState property will be set to '0'

Important: The lock item must be fully deleted even from the "Deleted Items" folder to revoke the lock.

Notes:
This function is necessary because it is possible that another process needed to update your item and has "revoked" your lock. This will only happen when running the TeamScope TeamWorkÔ product in Agent mode, or by some other process of your own which would delete the corresponding lock item. There are cases were the workflow agent needs to progress items and cannot wait. This would typically only happen if you have the item open for a long period of time.


CloseLibrary

For processes that call the library outside of an Outlook form. This is not needed for standard Outlook form operation since the library automatically closes when the item that referenced it is closed.

oLib.CloseLibrary


CopyGridProperties

Copy the properties from one OlGrid control to another. This is designed to be used primarily with the PrintForm function to make it easier to print out grid controls.

CopyGridProperties SourceGridControl, TargetGridControl

SourceGridControl: (Control Object) The OlGrid control that you are copying the properties from

TargetGridControl: (Control Object) The OlGrid control that you are copying the properties to

Note
This function copies most all of the physical attributes and data of a Grid control. There are certain properties that is does not copy such as the X & Y location and controls size for obvious reasons.

Code Example:

Set oGridToPrint=Item.GetInspector.ModifiedFormPages("Print").Controls("grdPrint")

oLib.CopyGridProperties oGrid, oGridToPrint

oGridToPrint.Rows=21 ' Limit or add rows to fill out printed form

oGridToPrint.FormatWidth="400|0|1500|4500|1000" ' Adjust properties to better fit printed form


CurrentItem

Defining the current item

OEL normally operates by attaching to the current Outlook item automatically. In some cases it is necessary to tell OEL what the current item is. This is the case for any external process that does not start from an Outlook form. This is also the case for Outlook 97 and 98 if the first visible page of the form has not been modified. For all Outlook 2000 forms this function is not necessary.

Set oLib.CurrentItem = OutlookItem

OutlookItem The current Outlook item. This is defined by default in an Outlook form as "Item"

Call during: This must be called immediately after instancing the library object.

Notes:
This function will set the HomeFolder property


Decrypt

Encrypting information

This function will convert a encrypted (Encrypt) data string of characters into a normal text string so it can be displayed and updated by a select group of authorized users

ClearText = Lib.Decrypt (SecureText)

Clear text Unencrypted text

Secure text Encrypted text.

The access control for this function is stored in the workflow template with the key "CryptoAccessResolved".

See: Fields Support for more information

Example:

Function Item_Open() ' Display the secure data into an unbound text field

...

t = oLib.Decrypt(Item.UserProperties("Secure Access Data"))

If t = "**********" Then opOrder.Controls("txtSecure").Enabled = False

opOrder.Controls("txtSecure").Value = t

...

End Function


DisplayErrors

Error handling

The Outlook Extensions Library supports two different modes of error handling. The two modes are determined by the value of the DisplayErrors property.

oLib.DisplayErrors = True | False

True (Default) In this mode, errors occurring within OEL are always displayed in a verbose error dialog. This error-handling mode is quite useful when you are first debugging your code in the design phase. The actual error is canceled (Err.Clear), but any subsequent call may continue to fail if there are any dependencies. This mode should not be normally used for handling run-time errors.

False In this mode, OEL errors are always raised programmatically and must be addressed via standard VBScript error handling techniques. The Error codes (Err.Number) are given the Appendix

VBScript error handling example:

On Error Resume Next             ' Required to handle errors... no GoTo support in VB Script

oLib.DisplayErrors=False         ' Turn on display mode error handling

Do

t=InputBox("Enter the history field name")

t=oLib.History.GetInitialValue   'This library function generates the error if the field name in string 't' is not valid

If Err.Number Then

MsgBox Err.Description      ' Display the error text - optional

Msgbox Hex(Err.Number)      ' Should be: 8004 0F40 in hex - optional

Err.Clear                   ' You must now clear the error before trying again.

Else

Exit Do                     ' No error, so now exit Do-Loop

End If

Loop


Encrypt

Encrypting information

This function will convert a normal text string into encoded characters that can only be decoded (Decrypt) by a select group of authorized users

SecureText = Lib.Encrypt (ClearText)

Secure text Encrypted text.

Clear text Unencrypted text

The access control for this function is stored in the workflow template with the key "CryptoAccessResolved".

See: Fields Support for more information

Example:

Function Item_Write() ' Update the secure data if the user has access

...

t = oLib.Encrypt(opOrder.Controls("txtSecure"))

If t <> "**********" Then Item.UserProperties("Secure Access Data") = t

...

End Function

Notes:
This function cannot be used until the item has first been saved.


ExitState

The exit state property is used to determine the state of the item in preparation for closing and saving the item.

Number = oLib.ExitState

- or -

oLib.ExitState = Number

ExitState values and what they mean:

>0 Either the History.process or Workflow.process have a need to save the form

=0 The History and/or Workflow or have checked but do not need to save the form
(Also, if the library CheckLock has determined that the user can't save the form)

=-1 The user has requested to cancel the form by hitting "X" or "Esc". (The Item_Close event)

=-2 The library Workflow.Process has determined that the data is not valid

=-99 The form has been initialized but no form closing or writing events have been called yet


GetFolderFromURL

GetFolderFromURL (Same as Navigate)

Retrieving folders and Navigating the folder hierarchy

This function returns a folder based on a specified path. You can think of this function as both providing a way to specify a folder from a URL (GetFolderFromURL), or as a way to navigate between folders (Navigate). Both GetFolderFromURL and Navigate are just different names for the same function. The important feature of this function is the many different ways the folder path can be specified.

Set Folder = oLib.GetFolderFromURL (PathName)

-or-

Set Folder = oLib.Navigate (PathName)

Folder: (Folder Object) Returned Outlook.MAPIFolder object

PathName: [ \\Store ] [ \ ..UpPath1\ ..UpPath2 ] \DownPath1\DownPath2\DownPath3\
Leading and trailing "\" are optional except when specifying the \\Store.
Path name after ".." is for comment only, since it uses the objects parent property.
The optional "\\Store" and "..UpPath" sections are mutually exclusive.

Examples:
Absolute URLs ... different ways to get to the "Configuration" folder

Set oFolder= oLib.GetFolderFromURL("<Outlook:\\My PST File\Application Folder\Configuration>")

Set oFolder= oLib.GetFolderFromURL("\\My PST File\Application Folder\Configuration")

Set oFolder= oLib.GetFolderFromURL("\\Public Folders\All Public Folers\Application Folder\Configuration")

Relative URLs ... assuming that you are starting form the "Configuration folder"

Set oFolder= oLib.GetFolderFromURL("..\") ' Go up to the Application folder

Set oFolder= oLib.GetFolderFromURL("Locks") ' Go down to the Locks folder

Notes:

You cannot navigate across information stores; however, you can specify any store absolutely using "\\Info store\...". Relative navigation is much faster then absolute navigation especially if your Public Folder hierarchy is large. Passing a blank path will return the current folder. The Navigate function also supports the <Outlook:\\ ... > absolute path URL declaration. Furthermore, if the URL is an item reference (i.e. it ends with the ~Subject syntax), the Navigate function will correctly ignore this and return the folder that the item is located in.

If navigating up one folder only you must specify it like "..\". Specifying only ".." will cause an error.

Important: In order for URL to work properly, make sure that no folder has a "/" or "\" in its name!

See: URL based functions, GetURL, GetItemFromURL

Important notes when working off-line:

Navigating up ".." will not work when operating off-line. (See Off-line and Distributed operation for more information.) If you need to get to a folder and be guaranteed that the form will work off-line, use the standard Outlook GetFolderFromID function.

While running off-line, Outlook URLs are case sensitive!

Favorites:

When operating off-line, your actual URL path will be different than when operating directly from a Public Folder. The Navigate function will automatically detect that you are operating off-line and will search the Favorites for a matching subset path in your URL. This means that the full-length URL to a Public Folder will operate off-line! Below is an example:

Original URL:

<Outlook:\\Public Folders\All Public Folders\International\USA\MIS\My Folder>

URL of above example when off-line in Favorites:

<Outlook:\\Public Folders\Favorites\MIS\My Folder>

The Navigate function will look under the Favorites folder for a match in the original URL going from left to right. In this example, the match will be found at the folder "MIS".

Note that there are two conditions that must be met for off-line URLs to work correctly:

1) Proper PublicFolderRoot registry key has been entered to match your language setting

2) Each folder in your URL string must have a unique name and thus cannot repeat


GetItemFromURL

Retrieving items from a URL

This function returns an item based on a specified path and unique item subject. This function is very similar to the GetFolderFromURL but acknowledges the additional Outlook item subject "~" qualifier. This function is in essence the inverse of the GetURL function.

Set Item = oLib.GetItemFromURL (PathSubjectName)

Item: (Item Object) Returned Outlook item object

PathSubjectName: ... some folder path....\~Item Subject
(for the folder path specification see: GetFolderFromURL)

Example: (Absolute URL)

Set oItem= oLib.GetItemFromURL("<Outlook:\\My PST File\Application Folder\Configuration\~SomeItem>")

Example: (Relative URL)

Set oItem= oLib.GetItemFromURL("\Configuration\~SomeItem") 'Assuming you are starting from the application folder

Notes:

For Outlook hyperlinks to work the subject in the folder must be unique. This in one of the main reasons for the GenRefID function in this library. There are some characters that you can place in a subject field that will cause an Outlook hyperlink to fail even though this function will return the "proper" URL for it.

Some situations that will cause link failures:

  • "/" or "\" in the folder path

  • Item subjects with spaces at the end

  • Items subjects with a three characters (not a number) followed by a ": "


GetPropertyValue

GetPropertyValue

This method is for use in the Item_CustomPropertyChange and Item_PropertyChange events. The GetPropertyValue method returns the value of the changed property. See Callback and Data change events for more information.

PropertyValue = oLib.GetPropertyValue (PropertyName)

PropertyValue: Value of the PropertyName field.

PropertyName: Name of field as given by the event.
Note: By default, Outlook simply calls this variable "Name"

Notes:

With any Outlook field set to perform an automatic calculation, events will occur before you even have the chance to create a reference to the OEL. Therefore, you may need to put an "On Error Resume Next" command before using this function, in case the Library reference variable (oLib in this example) is not yet a valid object. This function is required in the Property Change events if you want to perform event tracing (See: TraceOn)


GetURL

Getting a text URL

Returns the full path, in Outlook text URL format, to a folder or message. Use this method to generate text URLs for placement in messages (text bodies), to allow easy one-click linking to other messages or folders.

Text = oLib.GetURL ( Message | Folder )

Message: (Message Object)

- or -

Folder: (Folder Object)

Text: Full text URL path to message or folder.
Returned URL format: <Outlook:\\Store\Folder\Another Folder\~message subject>

See: URL based functions, GetFolderFromURL, GetItemFromURL

Notes:

When an item is created, and before it has been saved, the parent of the object is unknown and thus this method is not available.

Also, when operating off-line, this method will return the path as available from the Favorites folder, which will not be the same link as when the item is back on-line. If you need on-line and off-line functionality, use GUID-based links instead.

You can find more information on off-line use in the Appendix (Off-line & distributed operation).


GenRefID

Generating a unique reference ID

This function is important because it is absolutely necessary to have unique subject items in a folder for any hyperlink (URL) based functions to operate. Please review the URL based functions section for more details.

Format 1

Text = oLib.GenRefID [(FormatString)]

Called during: Item_Open event

Text: Returned ID string (usually then assigned to your items Subject to insure its uniqueness)

FormatString: (Optional) Format of the reference ID. Uses the basic date/time Format string parameters, along with special "Alias" and "Site.Alias" addressing values.
Default="Alias YYYY-MM-DD HH:NN:SS"
Alternative format: "Site.Alias & date time formatting"

Example output: smithj 1998-03-11 21:07:39

Format 2

Text = oLib.GenRefID ("Sequence")

The format string "Sequence" causes the function to return the next number in a sequence. The sequence number is automatically stored and updated in a configuration message called "GenRefID Sequence". Before you use this function you must set the Config folder location. Please note that although the process to get a sequence is very fast there is still a possibility that two users could generate a conflict and duplicate number. Keep this in mind as you consider scaling. Also, although technically this function will work off-line it will of course erroneously generate duplicate numbers. You may want to bypass or disable this function by checking the OnLine function.

See: URL based functions

For example, to set a unique Subject during the Item_Open event when the item is new:

      If Item.EntryID="" then

Item.Subject="2000 "+oLib.GenRefID

      End If

Alternative:

Many times desirable to have the subject actually contain a useable subject but it is still essential to make sure it will remain unique. One handy solution is to put a series of spaces at the end of the subject. The number of spaces is in effect generated randomly by using the current second time. You must append the spaces with a character like "." in this case. The advantage of using this space format is that it best preserves the look of the subject line.

Item.Subject=Item.Subject+Space(Second(Now))+"."


HomeFolder

Determining the correct folder

Returns the correct folder of the item that is active. This method is designed to always return the location of the folder where the item is running from. This can at times be different than ActiveExplorer.CurrentFolder, if the form was referenced (linked to) from a different folder.

Set FolderObject = oLib.HomeFolder

FolderObject: Outlook Folder Object

Notes:

To make sure your form works properly, you should always use this in place of ActiveExplorer.CurrentFolder.


ItemProperties

The ItemProperties function is provided for a couple of reasons.

  • Provide a simplified and unified way to access field data without having to deal with the "Custom" flag of Outlook's Item.UserProperties function.

  • Using Outlook's Item.UserProperties function for even reading many built in fields causes the form to one-off. One-offing your forms will unintentionally reset the message class of your form and will cause the item to grow in size dramatically!

  • Fixes some inconsistencies in properties across items. For example it adds a very important "Contacts" property that reflects the items links collection.

Reading a property value

Value = oLib.ItemProperties(FieldName [,Item])

Setting a property value

oLib.ItemProperties(FieldName [,Item]) = Value

FieldName The name of the native or custom field (String)

Item (Optional - Item Object) The item which you want to get the field value from

Value The value being read or written (Variant)

Note
This function does not display a UI error dialog regardless of the state of DisplayErrors. It will however raise an internal error if you need to trap it. (ERR_PROP_READ = &HF05 ERR_PROP_WRITE = &HF06) Using the Item.UserProperties on custom field is not problematic. In fact, for custom fields, the ItemProperties function simply calls this function.

See: Fields Support

Important note:

Currently this function will only work properly for "English" named properties. The "Language" setting in the registry tells OEL whether to use this special mode of operation. For language setting other than "English" the function will revert back to Outlook's native behavior and will unfortunately potentially one-off the item.

"Contacts" Field note:

In the ItemProperties function the "Contacts" field is synthesized from the links collection. This links collection is only available for Outlook 2000 users. For users of earlier versions of Outlook this function will simply return a blank "". This is so this important field can be used in a mixed client environment and will not cause errors.


License

Getting the Extensions Library license information

Text = oLib.License

Text: Returns the license information for the extensions library. This text contains a couple of data keys:

Org:
If the product is registered it will contain a reference to your Exchange Organization. Example: Org=Microsoft

Mode:
If the product is registered it will contain the type of license: Mode=Lib, Mode=User or Mode=Agent

Date:
If the text string ends in a calendar date, the installed Library will expire on the stated date. (Note: In this case, a warning message will begin appearing 30 days in advance of the expiration date.)

See: Client Registration for more information on licensing


LockState

Check the state of your lock

Text = oLib.LockState

Called during: After initial call to SetLock or CheckLock

Text: After SetLock: If the item is already open by another user, then the return text will contain information on who has the item open, and since when. If no lock has been set and the current item is available for editing, then the return string is empty.

After CheckLock: If the item has been "revoked" by another process then the value will contain an error string. If the item is still ok then the return string is empty.

Notes:
You can use this LockState property in customizing your form to provide lock notification, and/or you can actively disable any controls as necessary on a locked item. Note that the value returned here is static and is only valid after the SetLock or CheckLock functions have been called.


OnLine

Connection State

Flag to indicate whether you are connected to an Exchange server or operating on off-line Favorites.

Flag = oLib.OnLine

Flag: (Boolean) True=on-line connected to Exchange server, False=off-line

The setting of the "PublicFolderRoot" registry setting will effect the operation of this property.

See: Off-line & Distributed Operation


OutlookVersion

Getting the version of Outlook the user is running

Text = oLib.OutlookVersion

Text: Will return "97", "98" or "2000".

See: Outlook Specific Functionality

Notes:

This function is available in OL 2000 under the Application object, but is not available in prior versions of Outlook. All versions of Outlook provide a form description version, but this value only provides the version of Outlook that created the current item, not the version of Outlook the user us actually running.


PrintForm

WYSIWYG form printing

This method prints a graphical representation of your Outlook form to the default printer. You can choose between a vector-based reconstruction of the screen, or a simple screen bitmap dump of an Outlook form page.

oLib.PrintForm Page[,BitMap][,LandScape][,NoWrap][,X1,Y1][,X2,Y2]

Page: Name of the form page to be printed

BitMap: (Optional) True if you want a bitmap dump, False for Vector printing (default)

LandScape: (Optional) True if you want to print in Landscape orientation, False for portrait (default)

NoWrap: (Optional) True if you want text to disable line wrapping, False for auto wrapping (default)

X1,Y1: (Optional) Left, upper margin. (number in pixels) Default = 0,0

X2,Y2: (Optional) Width, height scale. (number in pixels) Default = form size (InsideWidth/Height)

Example: Printing the Grid

Printing Forms Notes:

The ability to print data from an Outlook form in a formatted layout as high-resolution lines (vectors) is a very useful function. The PrintForm method recreates the form by completely redrawing the controls, based on the information contained in their properties. Although the PrintForm function is WYSIWYG in concept, it may take some adjustment in practice to get the exact form layout you desire.

The parent tab form can be a scrolling view to make a full size printout on a less than full size form.

Some properties are not supported because they have only on-screen functionality. For example, a command button is of little value when printing and is thus omitted in the printout. If you wish to capture all controls in their on-screen format, use the bitmap printing option.

Properties Supported:

X & Y Position

Height & Width

FontName

FontSize, Bold, Italic, Underline...etc.

Visible

BorderStyle
TextAlign

Value

Properties Not supported:

SpecialEffect (3-D) Use BorderStyle=1 if you want a border

AllColors (printout is always back and white)

Some controls are not supported because they do not have a printable representation.

Controls Supported:

Control: Properties: (in addition to those listed above)

Frame Caption, BorderStyle=0 or 3D: Dashed Line, BorderStyle=1: Solid Line

TextBox Text, MultiLine

Label Caption

ListBox MultiSelect, ListStyle (Note: Single column only! See OlGrid)

CheckBox Alignment, Value (see note below)

OptionButton Alignment, Value (see note below)

Image Picture, PictureSizeMode

OLGrid Many properties; also see following sections

Note

The print function cannot tell the difference between a CheckBox and an OptionButton. To allow for correct operation the print function looks at the first character of the name to make a determination. By using the standard control naming conventions of "chkXXX" for a check box and "optXXX" for a option button the print function will then work.

Controls Not Supported:

CommandButton

ToggleButton

MultiPage

TabStrip

ScrollBar

SpinButton

Body Outlook gets upset when you use more than one " _DocSiteControl1" on a form. To get around this issue, you can transfer the body text content to a TextBox control with the Multi-Line property set to use in printing. No additional field is necessary since the body text information can be sent directly to the controls text property. Note, though, that all rich text information will be lost except for that of the properties of the control.

OlCal For compatibility reasons with the Outlook calendar object, you cannot print a calendar Control. You can however, simply bind a standard text field which can be printed to the date field that is being controlled by the calendar control.

OlGrid supported properties :

The OlGrid is a very powerful control and has many properties. To help in printing consider using the CopyGridProperties function. Our print capabilities support most of the important aspects of a grid:

ExtendLastCol

FixedRow / FixedCol

GridLines

ColAlignment

ColFormat

ColWidth

CellChecked

CellFont Name, Size, Bold, etc.

OlGrid properties not currently Supported:

RowHeight All rows are assumed to be the same height. RowHeight(0) will be used for all rows. Also, there is no vertical centering of cell contents, so it is best to make the RowHeight match the font of the grid.

GridLinesFixed

Outlining Collapsed rows and subtotals

CellAlignment See ColAlignment

ColIsVisible You are allowed to set the ColWidth to "0" which will hide the column

Pictures in cells

WordWrap Only one line is displayed per row

AllowPageBreak One page only, see below

All color properties

Printing - other limitations:

At this time there are some additional limitations in the PrintForm function.

1) No support for multi-pages and page breaks. Single page only.

2) The OlGrid will auto-expand down a page based on the number of rows it contains; however, all non-Grid controls must be placed above the Grid to avoid potentially being overwritten. For instance, a Total Amount text box below the grid will remain in its position on the form. If the Grid is smaller or the same size as it was allotted on the form, then this will work. However, if the Grid expands beyond its size on the form because of the number of rows, it will simply write over the top of the Total Amount control.

3) Complex multi-page totals etc. The FormPrint function is designed for basic single page forms. You can have more than one print form if you need different printing for the same form. If you need true reporting this can be done using our Workflow Analyzer product which can dump all workflow information to MS Access.


SetFormPos

To set the form position on the desktop:

oLib.SetFormPos Left,Top

Left: The desired position of the left side in pixels (integer)

Top: The desired position of the top side in pixels (integer)

See: SetFormSize


SetFormSize

To set the form size:

oLib.SetFormSize Width,Height

Width: The desired width in pixels (integer)

Height: The desired height in pixels (integer)

See: SetFormPos


SetLock

Request that an item lock be granted:

oLib.SetLock FolderName[,ItemToCheck]

FolderName: Name of the folder, directly under the configuration folder, in which to store lock records. Typically the "Locks" folder as shown in the basic folder setup.
TeamWorkÔ only: If the LockFolder field is set in the Workflow Configuration file, then this parameter is optional.

ItemToLock: (Optional - Object) The item to check the lock for. This option allows you to check another item besides the current item. By specifying another item to check, a lock is checked but never generated for that item. If this parameter is omitted, the lock will apply to the current Outlook item. Locks can only be generated if this parameter is omitted.

Called during: Item_Open event: After SetFolder has been specified

Sets: LockState property:
a) "" if lock has been granted to the user
b) "The name of the person and when the item was opened" if the item is locked by another user

Notes:

  • If getting a lock is successful, then a lock record item is generated in the specified folder. If desired, you can directly access these lock records and determine who has locks on what items by viewing the fields as shown below.

  • SetLock will automatically recapture any existing lock item by the same person, if somehow the lock gets left open. This case should be rare, but may happen if the users computer hangs and Outlook is restarted.

  • An items lock record is automatically removed by the CloseLibrary method or upon exiting the form.

  • Locks can be revoked (deleted) to block the user from being able to save the open item (See: CheckLock)

The lock record (IPM.Post) format is very simple:

Subject = GUID of the item that is under lock

BillingInformation = Subject of the item

CreationTime (Received) = set by system
SenderName (From) = set by system


TraceOn

Turn on event and data tracing

The tracing functionality is for use in the Item_CustomPropertyChange and Item_PropertyChange events. This function provides automatic event and data tracing to a log file. See Callback and Data change events for more information.

oLib.TraceOn TraceFileName [, FieldList]

TraceFileName: Name and path of file to write trace log to.

FieldList: (Optional) If you specify one or more fields, then only these fields will be traced.
This is useful because some fields such as the OlGrid callback can cause a great deal of event traffic and you may want to only trace fields of particular interest. If you leave this field blank, then all fields will be traced

Notes On Tracing:

Note that tracing can be slow because of the amount of events that occur. You should only turn it on for testing/debugging purposes. Keep in mind that any calculated fields or Outlook-mandated functionality will automatically generate PropertyChange events when other properties change. Note that the actual function that traces the events is the GetPropertyValue. This function must be included in the Property Change event for tracing to operate.

See: TraceOff, Callback Events & Tracing

To provide code flow tracing/debugging, you can set a field to values at various points in your script code. You can use one of Outlooks "spare" built-in fields, like Item.BillingInformaiton or Item.Mileage, to avoid the UserProperties syntax burden.

oLib.TraceOn "c:\temp\OlTrackInfo.txt","Mileage"   ' here we are only tracking the Mileage field
......
Item.Mileage = "Hello Trace log, I have reached that line of code"

The TraceOn function overwrites the specified file every time it runs. If you want to keep separate trace files, you can use:

Lib.TraceOn "c:\temp\OlTraceInfo " & Minute(Now) & Second(Now) & ".txt"


TraceOff

Turn off event and data tracing

Turn off event log tracing as set by the TraceOn

oLib.TraceOff

See: Callback Events & Tracing


Version

Getting the Extensions Library version number

Text = oLib.Version

Text: Returns the version of the library. The format is two digits each for major, minor and revision.
For Example: version 2.4.11 is returned as 020411

Notes:

It is good practice to check the version of the OEL just after setting the reference to it, to insure that the users installed Library is consistent with the version necessary to support your custom Outlook form.

See: Revision History


SetFolder

Setting Configuration Folder location

Outlooks message-data functionality is provided by the Config object. Before any of the Config data functions can be used, the location of the messages that contain the data must be established. For performance reasons, all data message items are presumed to be located in one folder for any one application. If you wish to store data messages in different folders, then you can re-specify the "config" folder location; just be sure to immediately return to the original location at all times to avoid problems, especially if you are using TeamWorkÔ Workflow.

To specify the folder location of your applications configuration message item(s):

oLib.Config.SetFolder FolderPath [,FolderEntryID, FolderStoreID]

FolderPath: \..up1\..up2\Down1\down2\ See the GetFolderFromURL function for more details. Note that you can set the Folder Path to "" which will reference the current folder. This blank path eliminates the need for a separate configuration folder for simple applications.

EntryID, StoreID: (Optional for online use) If want to be able to support links from items in separate folders while running off-line, you need to specify these GUIDs. This is to overcome the off-line issues of folder navigation. Note for TeamWork Workflow users: The Entry and Store GUIDs are for the workflow folder, not the configuration folder. The FolderPath finishes the navigation to the configuration folder.

Call During: Typically the Item_Open event. Must be called before any "Config" functions are called.
If off-line, this must be set before any GetFolderFromURL functions are called.

See: Config Data


ReadMsgData

Return all of the data in a configuration message

Typically this function is used to populate the values of lists (as in Listbox or Combobox controls) based on information in folder data messages.

Values = oLib.Config.ReadMsgData (Subject [,Section][,Cache])

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: (Optional) Name of section under which data resides

Cache: (Optional; default=True) To disable caching of a message read, set to False. (boolean: True/False)

Values: (Variant) Return array of values in the message

Note:

The data is read into the variant array until either the end of the file, a blank line, or the beginning of the next section. Individual data elements are separated by their placement on separate lines (delimiter = <CR>).

See: Config Data

Example:

vData=oLib.Config.ReadMsgData("My Data Item","Departments") would return:

vData(0)=Finance, vData(1)=Legal, vData(2)=Engineering


ReadMsgEntry

Read information from an INI message

Return a single Value of a known Key= in a [Section]

Value = oLib.Config.ReadMsgEntry(Subject,Section,Keyname[,Cache])

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: The name of the section as defined with square brackets "[ ]" around it

Keyname: The name of the key which has an equal sign "=" to its right

Cache: (Optional; default=True) The OEL normally caches data message reads for better performance. To disable this caching, set this parameter to False. This option would typically only be used if the contents of the message item will be changing while this session (item) is active.

Value: The returned Value from the key. (String data from the right side of the "=")

See: Config Data

Examples:

oLib.Config.ReadMsgEntry("My Data Item","Colors","Green") would return "2"

oLib.Config.ReadMsgEntry("My Data Item","Size","Medium") would return "{{FieldX}}"


ReadMsgEntryVar

Return a single value of the specified key

This function is designed for use in conjunction with TeamScope's TeamWorkÔ Workflow product but can be used for a variety of purposes. It returns a single Value of the specified key, with all included {{fields}} replaced (redirected) with their values. This method is similar to ReadMsgEntry, except that it also performs replacement of variables with their values. See Configuration Field Redirection for more details on dynamic field string building.

Value = oLib.Config.ReadMsgEntryVar(Subject,Section,Keyname,Item)

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: The name of the section as defined with square brackets "[ ]" around it

Keyname: The name of the key which has an equal sign "=" to its right

Item: (Object) The actual message "Item" object

Value: Value of the key after {{field}} redirection is complete

Note:

The ReadMsgEntryVar function always uses caching.

See: Config Data, Config Field redirection, Simple form letter Example

Examples:

oLib.Config.ReadMsgEntryVar("My Data Item","Color","Green", Item) would return "2"

oLib.Config.ReadMsgEntryVar("My Data Item","Size","Medium", Item) would return "77"


ReadMsgSection

Return all of the keys and values in a configuration section

oLib.Config.ReadMsgSection Subject,Section,NameArray,ValueArray[,Cache]

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: The name of the section as defined with square brackets "[ ]" around it

NameArray: (Variant) Return array of key names in the section

ValueArray: (Variant) Return array of key values in the section

Cache: (Optional; default=True) To disable caching of a message read, set to False.

See: Config Data

Example:

oLib.Config.ReadMsgSection "My Data Item","Colors", vKeys, vData

would return: vKeys(0)=Red, vKeys(1)=Green, vKeys(2)=Blue ...and...

vData(0)=1, vData(1)=2, vData(2)=3


ReadMsgSectionList

Return all of the section names in a configuration message

Values = oLib.Config.ReadMsgSectionList (Subject[,Cache])

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Cache: (Optional; default=True) To disable caching of a message read, set to False.

Values: (Variant) Return array of section names in the message

See: Config Data

Example:

vSect=oLib.Config.ReadMsgSectionList("My Data Item") would return two elements:

vSect(0)=Colors, vSect(1)=Size


AddMsgSection

Add a new section and keys in an INI message

Adds a new section and related set of data keys in a message.

oLib.Config.AddMsgSection Subject,Section,DataKeyNameValues

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: The name of the section as defined with square brackets "[ ]" around it

DataKeyNameValues:
Parameter array of values, variables or array variables
This parameter supplies the list of keys or data items that are to be included under the new section (in the form of list elements separated by ","). These data keys can be of any of the supported formats.

See: Config Data

Example:

olib.Config.AddMsgSection("My Data Item","United States","Alabama=33,9","Alaska=45,0","Arizona=11,3")

would produce this new section in the "My Data Item" message:

Notes:

If the message is cached, the cache will be automatically updated. The section to be added must not already exist or an error will be generated. See: DeleteMsgSection


DeleteMsgSection

Delete a message data section

Remove an existing section in a data message.

oLib.Config.DeleteMsgSection Subject,Section

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: The name of the section as defined with square brackets "[ ]" around it

Notes:

If the message is cached, the cache will be automatically updated.

See: Config Data

The following example adds a new entry to an existing section of a message:

vArray = oLib.Config.ReadMsgData("MyMessage","MySection",False)

oLib.Config.DeleteMsgSection "MyMessage","MySection"

oLib.Config.AddMsgSection "MyMessage","MySection",vArray,"NewEntry"


MsgEntry

Write (update) information in an INI message

Update a single Value of a known Key= in a [Section]

oLib.Config.MsgEntry(Subject,Section,Keyname[,Cache])=NewValue

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: The name of the section as defined with square brackets "[ ]" around it

Keyname: The name of the key which has an equal sign "=" to its right

Cache: (Optional; default=True) To disable caching of a message, set to False. If a cache for this message already exists, it will be updated automatically regardless. If caching is enabled (default), then after the item is updated, any following message-read operations will be much faster.

NewValue: The value that the key will be assigned to

See: Config Data

Notes:

The Key must preexist. If you wish to add a new key programmatically, do so by section using the AddMsgSection.


MsgDataValidate

Check the items in a Message Data list and see if the new value entered in a control is on the list. If the value is not on the list a dialog is displayed and the user is asked if they want to add it (See dialog below). It the users selects "Ok" then the new value is automatically entered into the list. If the user selects "Cancel" then old value is restored if it is being tracked in the history or is cleared.

oLib.Config.MsgDataValidate ConfigFile,Section,FieldObject[,SortFlag]

ConfigFile: The subject of a message in the preset "Configuration" folder (see SetFolder).

Section: The name of the section as defined with square brackets "[ ]" around it

FieldObject: (Outlook field) The field that the data is being entered into

SortFlag: (Boolean) Optional flag to turn on or off sorting of the list. Default=True = Sort

See: Config Data

This method must be called during the property or custom property change event for the field being validated. See the example below.

Case "Sub Region"

On Error Goto 0

tSection=Item.UserProperties.Find("Region")

Set oField=Item.UserProperties.Find("Sub Region")

oLib.Config.MsgDataValidate "Regions", tSection, oField


DisplayMsgFile

Display the configuration file

This function provides a convenient method for quickly displaying the selected (subject) message file. This is useful when debugging configuration files or providing a simple UI to update them.

oLib.Config.DisplayMsgFile Subject

Subject: The subject of a message in the preset "Configuration" folder (see SetFolder).

Return: Message data file in a new inspector object.

See: Config Data


Display

This method causes a folder window (Outlook Explorer) to be displayed. When the selected item is opened (double-clicked), the item's EnrtyID is passed to the specified callback field.

oLib.GetItems.Display TargetFolderPath, CallbackFieldName [,NumberOfReturnItems][,CallBackDelay]

TargetFolderPath: Relative path to folder. (See the Navigate function for details.)

CallbackField: Name of field to receive the callback updates. This field must be a custom (not built-in) Outlook field.

NumberOfReturnItems: Optional number of items to return. If =1 then the target Outlook Explorer closes after the item is chosen. If NumberOfReturnItems is >1, then the Explorer remains open. Default=1. (Integer)
Note also that double-clicking on same item a second time will open it.

CallbackDelay: Optional duration (ms) of delay before callback fires. Default=100 (.1 sec) (Integer)
It may be necessary to increase the delay time to some number >100 if you are opening custom forms. If you don't provide adequate time for the item to process its open event it can hang Outlook. This problem only occurs if the open event of the item is referencing controls on its own form.

See: Linking to other items

Notes:
During the callback event, the CallbackField will contain the entry ID of the selected message. You can select a range of items by first selecting them and then, with the right-click menu, select "Open Selected Items". After you are finished selecting, you should always close the target folder for performance reasons.


StopDisplay

Close the selection display window

If you have specified to select more than one item to be returned from the Display method then you can set this method to stop returning items and close the Outlook selection folder window.

oLib.GetItems.StopDisplay


UpdateLinks

Update the contact links collection. Outlook 2000 only.

oLib.GetItems.UpdateLinks [TargetItem]

TargetItem The item you are updating the links on. By default it is the current item. (Item Object) - Optional

The links collection in Outlook 2000 is used in a number of important roles. Unfortunately if links are not resolved or become orphaned they can become problematic. Even more annoying is if you change the name of the contact associated with the links the display name of the link does not update itself.

This function will automatically rebuild the collection:

  • Remove missing or non-resolved links

  • Update the display to reflect the correct name of the contact


Setup

Tracking the complete history of information as users edit the data in an Outlook form is a very powerful capability. The History object provides full tracking of any fields (even the message body!) including the before and after values for each change, as well as who made the change and when.

Set up History tracking

Set up History tracking by providing a list of field names to track

oLib.History.Setup Fields

Called during: Item_Open, before any changes to fields occur

Fields A delimited list of Outlook field names to track history for

Notes:

A special "Attachments" pseudo-field name can be specified to track an items Attachments collection.

Example:

oLib.History.Setup "Attachments;Body;Categories;DueDate;Size;Sub Region;Total Amount"

In most cases, if you are using history tracking in conjunction with a TeamWorkÔ workflow, you should store the delimited field list in the Workflow Configuration message under the HistoryFields key. This provides a non-hard-coded solution that is documented and supported by the Workflow Designer. It also then provides a field list for the Workflow Analyzer to use when exporting field data.

See: Change History


GetInitialValue

Read History values

Allows retrieval of History (pre-change) values.

Value = oLib.History.GetInitialValue (FieldName)

FieldName: The name of the field

Value: The value of the field when the History.Setup method was originally called

Call during: Any time after History.Setup is called

Note:

Any "WriteToField" operation will update the history values so it is best to.

See: Change History


WriteToField

Process (formally WriteToField)

Write out the change history to a field. In previous version of OEL this was called "WriteToField". This name is still supported and it is not required that you change it in your code.

oLib.History.Process DestinationField [,ChangeStringLength][,AppendOnTop]

DestinationField: Name of the history field in your form. Make sure the destination text field has its MultiLine property set to True and is set to read only.

ChangeStringLength: (Integer) Optional length of the change window. The default is 40 characters. This parameter defines the number of characters of data that will be included when a changed fields before and after data is recorded. (Also see Notes below for more on this parameter.)

AppendOnTop: (Boolean) Optional flag to indicate whether the latest change history is appended to top of the previous change history or at the bottom. The default (True) is to place the new changes at the top.

Modifies: The ExitState property is set to "0" if no changes are detected. If any fields have changed and thus need to be saved, the value of ExitState is incremented. You can use this ExitState=0 condition to cancel unnecessary form updating, by setting Item_Write=False and then closing by using Item.Close (olDiscard). See the example in the Exiting Your Outlook Form discussion

Call during: Item_Write

Notes:

Fields that have embedded carriage returns, or are longer than ChangeStringLength (default of 40) characters are handled in a special fashion. Any embedded carriage returns are replaced with "<CR>", the position of the first change is indicated, and the surrounding 2xChangeStringLength (default of 80) characters are displayed. If you post an item from an external process without setting the history text, it will be marked with the text ">>> Entry created by an external process".

See: Change History

Example History field output:

------------- UserA on 4/28/98 4:23:07 PM -----------

>>> Entry Created

------------- UserB on 5/22/98 10:30:11 PM -----------

Field: CustomerName changed from 'Bob's Airplanes' to 'Bob's Big Airplanes'

Field: DueDate changed from '' to '12/24/98'

------------- UserC on 5/23/98 8:36:38 AM -----------

Field: Body changed at (33) from 's company has great airplanes' to '<cr> Let's order the big one inste'

Field: FlowStatus changed from 'Approved' to 'Approved; Purchased'


ArrayToText

Converting an array to text

Converts an array or matrix to a delimited string.

Text = oLib.Support.ArrayToText (ArrayToConvert [,DelimiterChar][,NumColumns])

ArrayToConvert: Array of 1 or 2 (matrix) dimensions. (Variant Array)

DelimiterChar: Delimiter character(s). Default = <CR> - Optional

NumColumns Number of columns to wrap at. (Integer) - Optional

Text: The returned text string

See: TextToArray, VB Script Support

Array Examples:

MyArray="a,b,c,d,e,f,g,h,i" is an array of 9 elements

Example 1:

Text=oLib.Support.ArrayToText(MyArray)

Text =

a

b

c

d

e

f

g

h

i

Example 2:

Text=oLib.Support.ArrayToText(MyArray,";")

Text = a;b;c;d;e;f;g;h;i

Example 3:

Text=oLib.Support.ArrayToText(MyArray,";",3)

Text = a;b;c

d;e;f;

g;h;i

Matrix Example:

MyMatrix = ( a,b,c

d,e,f;

g,h,i )

Text=oLib.Support.ArrayToText(MyMatrix,";")

Text = a;b;c

d;e;f;

g;h;i


BeepTone

Attention sound

The BeepTone function provides an audible beep tone to alert the user.

Same as the "Beep" method in VB

oLib.Support.BeepTone [NumberBeeps]

NumberBeeps: (Optional) The number of time the beep will sound. Default=1 (Integer)

See: VB Script Support


ClipboardText

Text transfer with the Clipboard

Copy text to and from the Windows clipboard.

Read text from the clipboard:

Text = oLib.Support.ClipboardText

Write text to the clipboard:

oLib.Support.ClipboardText = Text

Notes:

These correspond to the standard VB GetText and SetText functions.

See: VB Script Support, Pasting Excel data


FormatString

The VB "Format" function

For some reason, the standard bread-and-butter VB "Format" function is not available in VBScript. This OEL method passes the VB functionality to VBScript.

Text = oLib.Support.FormatString( Expression, FormatText )

Expression: The value you are applying the format to.

FormatText: The user-defined formatting string, as supported in the VB Format function.

Notes:

§ Refer to the VB "Format" user-defined formatting strings in the VB help file for details on allowable values for the FormatText parameter.

§ Use the standard VBScript fixed format functions where they are appropriate.

See: VB Script Support


Replace

The VB "Replace" function

Versions of VB Script before version 5 (also IE 5) do not have the Replace function. This function is designed to replace this missing Replace function. If you have VB Script v5 there is no reason to use this function.

Result = oLib.Support.Replace( Source, Find, Replace [,Start][,Count][,IgnoreCase] )

Result: The returned text string

Source: The source (input) string

Find: The string you want to replace

Replace: The string you want to replace with

Start: The position to start replacing characters from. Optional - Default is 1 (the beginning)

Count: The number of replacements to make. Optional - Default is all

IgnoreCase: Flag: True=case insensitive, False=use exact case. Optional - Default=False (case sensitive)


RunShell

The ShellExecute API

The Windows API ShellExecute API function provides many powerful features:

  • Launch applications, with specified files if desired (this provides a similar functionality as that available via the Windows command-line)

  • Open specific web pages (provides programmatic links to the web!)

oLib.Support.RunShell File [, Parameters [, Topic]]

File: The Windows shell function you are requesting. Some examples:

Open a web page: "www.TeamScope.com"
Open a text file: "c:\MyTextFile.txt"
Open a document: "c:\MyDocument.doc"

Parameters: (Optional) This is only necessary to specify the file if the file extension is not associated with the desired supporting application. In that case, the "File" parameter is used to open the supporting application. Refer to the Windows Explorers View | Options | File Types dialog.

Example:

oLib.Support.RunShell ("NotePad.exe","c:\temp\File.xyz")

Topic: (Optional) In almost all cases, the desired topic (Action) is "Open", which is the default. Some applications support multiple actions, such as "Print" or "Play". Again, refer to the Windows Explorers View | Options | File Types dialog to review the actions that an application supports.

Notes:

This function uses the Windows ShellExecute API. A good article on ShellExecute usage can be found at http://www.mvps.org/vbnet/code/shell/shellexecute.htm.

See: VB Script Support


SortArray

Sorting elements in an array (ShellSort algorithm)

SortedArray = oLib.Support.SortArray(ArrayToSort [,CaseInsensitive])

ArrayToSort: Unsorted array of data. (Variant Array)

SortedArray: Sorted array of data. (Variant Array)

CaseInsensitive: (Optional Flag) Whether the sort is case insensitive or not. Default=True (not case sensitive)

See: VB Script Support


TextToArray

Converting delimited text to an array

Converts a delimited text string to an array (or matrix) with columns. The return array is zero-based.

Array = oLib.Support.TextToArray (TextToConvert [,DelimiterCharacter [,NumberOfColumns]] )

TextToConvert: Delimited text to be converted

DelimiterCharacter: Optional delimiter character(s). Default is carriage return. (ASCII 13)

NumberOfColumns: Optional number of columns before wrapping to next row. Default=1 column.

Array: Return variant array or matrix. Starting element is zero-based.

Notes:

§ Also works if a <CrLf> is included along with DelimiterCharacter (assuming that the DelimiterCharacter is not <CrLf>).

§ The default number of columns is one (1), which will generate a new row for each delimited item. If the number of columns is 1, then the return array will have only one dimension. If the number of columns is >1, then the return is a matrix where the second dimension contains the columns.

§ The returned array will be trimmed of any leading or trailing spaces and tabs.

OELs TextToArray is different than the VB Split function, in that TextToArray can return more than one dimension if requested, and also supports intermixed line and element delimiters.

See: ArrayToText, VB Script Support


TimerField

Timer Event

You can provide your own timer functionality by performing a loop and checking for a change in time. Unfortunately, this will cause your application to consume 100% of CPU resources and basically freeze your application. For this reason, OEL provides a true interrupt-based timer that allows your Outlook program to continue processing information and receive a callback when the specified interval has passed.

To set the field to receive the timer callback:

oLib.Support.TimerField = FieldName

Notes:

  • You must specify the TimerField before you specify the TimerInterval.

  • Important: The timer field must be a custom field. You cannot use a native (built-in) Outlook field for this.

See: VB Script Support


TimerInterval

To set the number of seconds between callbacks

oLib.Support.TimerInterval = NumberSeconds

FieldName: The name of a built-in or custom field that will receive the timer count via a callback.

NumberSeconds: The number of seconds between (i.e. interval between) timer callbacks. (Integer)

Notes:

  • The value returned in the specified field will increment by one for each specified interval. The minimum value of "1" corresponds to an interval of 1 second. The maximum value is 32767, which corresponds to just over 22 days.

  • To stop the timer, set the TimerInterval=0. This will also reset the counter to 0.

  • You must specify the TimerField before you specify the TimerInterval. Recall that in Outlook, not only is a field updated but an event is automatically generated in either the PropertyChange or CustomPropertyChange event which allows you to run any desired code when the interval expires.

See: VB Script Support


Setup

Setup sync data keyword field with desired recipients

oLib.Sync.Setup(RecipList, KeywordField [,DisplayGrid][,Item][,Clear])

RecipList: List of recipients that will receive copies
Example 1: "User A; User B; User C" All users will receive copies
Example 2: "User A=1; User B=1; User C=0" Only users with a '=1' will receive copies

KeywordField: Name of keywords field to hold sync data

DisplayGrid: (Optional - Control) Grid control object on your form if you want a UI

Item: (Optional - Item) Item to be sync'ed. By default it will use the current item
Only IPM.Appointment and IPM.Task are currently supported

Clear: (Optional - Flag) To clear out the sync data Default=False (Keep current data)

Call During: Item_Open

See: Item Sync, Process, Remove, Example

Notes
Once the keyword data is valid the recipient list is ignored. To change the recipients you must clear the keyword data by using the 'Clear' flag. Clearing the data will cause the items to be recreated and thus create duplicates. This function must be called at least once before the Process function is called.


Process

Publish out the item to designated private folders

oLib.Sync.Process(KeywordField [,LinkType][,DisplayGrid][,Item][,Force])

KeywordField: Name of keywords filed to hold sync data as set in the Sync.Setup. This data must eventually saved in the Item_Write event

LinkType: (Optional - Integer) Type of link to be included in sync'ed times that point back to the master item
0=None (default)
1=Hyperlink
2=GUID Hyperlink
3=Icon link
4=Contacts links collection (OL 2000 Contacts only)

DisplayGrid: (Optional - Control) Grid control object on your form if you want a UI

Item: (Optional - Item) Item to be sync'ed. By default it will use the current item
Only IPM.Appointment and IPM.Task are currently supported

Force: (Optional - Flag) To force items that have been deleted to be recreated Default=False

Call During: Data change event or Item_Write

Call After: Sync.Setup function has first been called

See: ItemSync, Setup, Remove, Example

User Mode Notes
Call this function anytime the master item has incurred any changes. Make sure to save the master item after calling this item to avoid any sync data status loss. Typically just calling this in the Item_Write event is sufficient.

Agent Mode Notes
In agent mode you as a client do not call this function but you need to send a notice to the workflow agent. Doing this is a simple process as shown in the agent example:

Interface:

To: Name of your workflow agent mailbox

Subject: "Item Sync" (This is the keyword that the agent uses as a trigger)

BillingInformation: Item.EntryID

Mileage: Name of items keyword field See KeywordField above

Categories: Link type (0,1,2,3 or 4) See LinkType above


Remove

Have the item removed from all recipients

oLib.Sync.Remove(KeywordField [,Item])

KeywordField: Name of keywords field to hold sync data

Item: (Optional - Outlook Item) Item to be removed. By default it will use the current item

See: Item Sync, Setup, Process, Example


Intro

Calendar OCX: Introduction

Standard Microsoft Outlook forms which include date-type fields (such as the Task and Appointment forms) include a drop-down monthly calendar as part of that date field. While various companies (including Microsoft itself) provide monthly calendar controls that can be used on an Outlook form, none of these provide the same design or functionality as Outlooks built-in control.

OlCal is a 32-bit ActiveX custom control that matches Outlooks built-in date field in both look and operation. The following sections highlight some of the unique features of OlCal.

Looks and feels like Outlook

OlCal reproduces very closely the look of the built-in Outlook drop-down calendar. Your users will probably not notice the difference!

Outlooks built-in Calendar OlCal

Includes textbox

The control includes not only the drop-down monthly calendar, but also the textbox portion of the date field. So it acts like a text control, into which you can type a date, or you can click the down-arrow next to the textbox and expose the monthly calendar grid to select a date by clicking on it.

Includes AutoDate capability
OlCal's textbox allows you to enter English-language date phrases, just like Outlooks built-in date control, and it will interpret them and convert them to a proper date format. For example, you can type in 5 days, or next Thur, or 3rd Sat in July.


Properties

OlCal supports a standard set of ActiveX properties; consult your Visual Studio documentation for details on using these properties.

In addition, OlCal implements the following custom properties. Use the control's "Advanced Properties" to access these additional properties.

AllowNone

[Default setting = True]

OlCal can be configured to allow None as a valid entry (as in the Due Date field on a Task form) or disallow the entry of None (as in the Start Time field on an Appointment form).

Set this property to True if the user is allowed to enter None as a valid date field entry; set it to False to prevent the entry of None.

OlCal with AllowNone=False OlCal with AllowNone=True

CloseOnDateClick

[Default setting = True]

When you click on a date on Outlooks built-in month drop-down calendar, the clicked date is immediately shown in the date fields textbox, and the monthly calendar closes. By default, with CloseOnDateClick set to True, OlCal reproduces this same behavior.

However, you may find it preferable to let your users click on the calendar while leaving it open; they can then choose when to close it. To enable this option, set CloseOnDateClick to False. With this setting, when the user clicks on a date, that date will be shown in the textbox, but the drop-down calendar will remain open. The user can change months or years, and can click a new date if desired. The monthly calendar is closed by clicking on the same arrow button that is used to open it up.

FirstDayOfWeek

[Default setting = 0]

You can configure OlCal to define the starting (leftmost) day of the week displayed on the monthly drop-down calendar.

The valid settings for this property are:

0 = Use Outlooks setting (default)

1 = Sunday

2 = Monday

3 = Tuesday

4 = Wednesday

5 = Thursday

6 = Friday

7 = Saturday

By default, OlCal will use the First Day of Week setting defined within Outlook (see Tools | Options | Preferences | Calendar Options | First Day of Week). Alternatively, you may set it to always begin on a predefined day of week.

IMPORTANT NOTE: OlCal determines Outlooks defined First Day of Week by reading a particular value from the Windows registry. If the control cannot locate the correct Registry entry, and this property is set to 0, then the message will be displayed: The calendar control cannot locate an installation of Microsoft Outlook on this computer.

This will occur if Outlook is not installed on the users PC. It will also occur if the user has never customized any of Outlooks calendar settings, because Outlook does not write the necessary Registry entry until one or more of its Calendar options has been changed.


Notes

Notes on usage

When placing OlCal on an Outlook form, you will notice that it exists at a fixed size only, and that it consists of two areas: a visible portion containing the textbox, and a transparent outline, which shows where the drop-down monthly grid will be displayed.

In choosing where to place the control on your form, it is perfectly acceptable to place the transparent portion of the control over top of another field or control on the form, since the calendar is allowed to open up in front of another control when the monthly portion is dropped down.

To save the value entered into an OlCal control, bind it to any Outlook date/time field (built-in or custom), just as you would bind any other control to a field.

Binding OlCal to a Field

The standard way to use OlCal is simply to bind it to a date-type field on your form. This is the recommended way to use the control.

One important note when doing this: be sure to leave the controls Format field set to its default setting of ddd, mm/dd/yy (for example, Thu 05/18/00). Using any other Format setting will result in a Type Mismatch error when a user attempts to set the date on the control. The only way to recover from this error is to delete the effected controls and add them back.

Placing OlCal Over a Listbox or other controls

As mentioned earlier in this section, OlCal contains an initially invisible region that contains the monthly drop-down calendar. In almost all cases, it is perfectly acceptable to place this portion of the control over top of another field on your Outlook form, since the calendar is allowed to open up in front of another control when the monthly portion is dropped down.

Due to an apparent bug in Outlook/MSForms, OlCal will not properly display itself if placed over top of an Outlook Listbox control. Please be careful not to place it over a Listbox control.

Issues with control layering (order):

  • Calendar area drops behind other controls (typically other Calendar or Grid controls)

  • Calendar area invisibly covers other controls and blocks any use of the controls

These issues are solved by adjusting the "order" of the controls involved.

Placing OlCal inside of a frame control:

Placing a calendar control inside an Outlook frame control where the drop-down area is larger than the frame will crash Outlook!

One work around is to use a image control with the "specialeffects" property set to "3-Etched". This image control looks just like a frame control once you put a label in the upper left hand corner.

Updating the bound field:

If you programmatically update the data field that is bound to calendar control it will not be reflected in the control. When the form is reopened the control will reflect the correct value however. This issues has no known work-around and we will be releasing a new version in the near future to fix this.

Pasting OlCal on a Form, or Placing a New OlCal Version on a Form

When cutting-and-pasting an OlCal control onto a form, or deleting an old OlCal version and inserting a new version on the form, you may find that other controls on the form either lose their field bindings, or their field bindings become scrambled such that controls are bound to the wrong fields.

So, whenever you are updating to a new version of the control on a form, or cutting/copying and pasting an OlCal, please be sure to check the remaining form controls to ensure that they properly bound.

Note that this behavior can also occur for other controls aside from OlCal, so be careful when performing the above-mentioned operations. The issue appears to be related to one mentioned in the Microsoft Knowledgebase; see article Q195233 for more information.


Intro

Grid OCX: Introduction

OlGrid is a 32-bit ActiveX custom control that provides a full-featured editable grid designed specifically for use on Microsoft Outlook forms.

OlGrid is based on, and encapsulates, Videosoft's 32-bit VSFlex7L.OCX grid control. OlGrid implements most of VSFlex's properties, methods, and events see the following section for details.

While theoretically a VSFlex grid can be placed directly on an Outlook form, one quickly runs into limitations: first, Outlook forms do not support any events other than the Click event for controls contained on them. In addition, no mechanism exists for binding Outlook data to the rows and columns of a grid, as is possible using standard data binding in Visual Basic.

OlGrid provides a solution for both of these issues. The lack of event notification is overcome by the use of a designated callback field. The designer of the form places a hidden text field on the form containing OlGrid, and provides OlGrid with the name of the field. Whenever a grid event occurs, OlGrid will call back to Outlook by placing information about the event in this text field. The forms CustomProperty_Change event fires whenever the value of the callback text field changes; code within this event then processes the contents of the field to determine what grid event occurred and act on it accordingly. See the descriptions of the OlCallbackField and OlEventTriggerLevel properties for more information. Probably the best way to learn how events work is to look at the TraceOn example.

OlGrid also includes several methods ArrayToGrid and GridToArray which allow for easy loading and saving of grid data to and from an Outlook field or a user-constructed data array. This provides a convenient way of binding MAPI (Outlook field) data to the grid.

Because our Outlook Grid encapsulates VSFlex Grid you get all of its features, such as:

· In-Cell editing, In-Cell combo box

· Merge cells, Subtotals & Outlines

· Graphics

· &.and much more

Refer to the included VSFlexGrid help file (VsFlex7.hlp) for details and examples of how make use of all of these features.

The Grid is used extensively in both the Outlook Extensions Library and TeamWork™ workflow system.

Order Demo

Workflow Demo

Code examples:

Pasting data from Excel

Printing the Grid


Grid Properties

VSFlex (7L) Properties Supported

The following VSFlex7L properties are supported by the OlGrid control. Please refer to the accompanying VSFlex documentation for details on these properties.

Aggregate (read only)

Align

AllowBigSelection

AllowSelection

AllowUserFreezing

AllowUserResizing

Appearance

AutoSearch

AutoSearchDelay

AutoSizeMode

AutoSizeMouse

BackColor

BackColorAlternate

BackColorBkg

BackColorFixed

BackColorFrozen

BackColorSel

BorderStyle

BottomRow

Cell (write only)

CellAlignment

CellBackColor

CellButtonPicture (read only)

CellChecked

CellFloodColor

CellFloodPercent

CellFontBold

CellFontItalic

CellFontName

CellFontSize

CellFontStrikethrough

CellFontUnderline

CellFontWidth

CellForeColor

CellHeight

CellLeft

CellPicture (write only)

CellPictureAlignment

CellTextStyle

CellTop

CellWidth

ClientHeight

ClientWidth

Clip

Col

ColAlignment

ColChecked (read only)

ColComboList

ColData

ColDataType

ColEditMask

ColFormat

ColHidden

ColIndex (read only)

ColIsVisible (read only)

ColKey

ColPos (read only)

ColPosition (write only)

Cols

ColSel

ColSort

ColWidth

ColWidthMax

ColWidthMin

ComboCount (read only)

ComboData (read only)

ComboIndex

ComboItem (read only)

ComboList

ComboSearch

Editable

EditMask

EditMaxLength

EditSelLength

EditSelStart

EditSelText

EditText

EditWindow (read only)

Ellipsis

Enabled

ExplorerBar

ExtendLastCol

FillStyle

FindRow (read only)

FixedAlignment

FixedCols

FixedRows

FloodColor

FocusRect

Font

FontWidth

ForeColor

ForeColorFixed

ForeColorFrozen

ForeColorSel

FormatString

FormatWidth

FrozenCols

FrozenRows

GridColor

GridColorFixed

GridLines

GridLinesFixed

GridLineWidth

Height

HighLight

IsCollapsed

IsSelected

IsSubtotal

Left

LeftCol

MergeCells

MergeCol

MergeCompare

MergeRow

MouseCol

MouseIcon

MousePointer

MouseRow

MultiTotals

OutlineBar

OutlineCol

PicturesOver

PictureType

Redraw

RightCol

Row

RowData

RowHeight

RowHeightMax

RowHeightMin

RowHidden

RowIsVisible (read only)

RowOutlineLevel

RowPos (read only)

RowPosition (write only)

Rows

RowSel

RowStatus

ScrollBars

ScrollTips

ScrollTipText

ScrollTrack

SelectedRow (read only)

SelectedRows (read only)

SelectionMode

SheetBorder

ShowComboButton

Sort (write only)

SubtotalPosition

TabBehavior

Text

TextMatrix

TextStyle

TextStyleFixed

Top

TopRow

TreeColor

Value

ValueMatrix (read only)

Visible

Width

WordWrap

OlGrid Properties Added for Outlook

In addition to the supported set of VSFlex properties, OlGrid implements the following properties to support Outlook:

OLCallbackField

Contains the name of a Text or Keywords field on your Outlook form that will receive event information from the OLGrid control. Because the Outlook forms model does not provide complete support for ActiveX events (in fact, only the Click event is supported), OlGrid implements event notification via this separate callback field on the Outlook form.

To implement grid event support, first add a Text or Keywords field to your Outlook form. This will be the callback field. This field must be physically present on the form to operate. You can hide this field behind the Grid or make it invisible.

Initialize the grids event callback capability by setting the grids OLCallbackField property to the name of this Text or Keywords field. This callback property may be set either at design time using the Advanced Properties list, or at runtime in the forms Item_Open event. If setting at runtime, be sure to set this property before attempting any other operations that use the OLGrid control.

Then use a CustomProperty_Change event in your forms script to respond to the appropriate control events.

Following is a code sample illustrating the use of callbacks. Note: the oLib.GetPropertyValue call references a method from the Outlook Extension Object library (OLEXTEND.DLL).

Sub Item_Open()

oGrid.OLCallbackField = GridCallback

.

.

End Sub

Sub CustomProperty_Change(Byval PropName)

PropVal = oLib.GetPropertyValue(PropName)

Select Case PropName

Case "GridCallback"

Select Case PropVal

Case "DblClick"

Msgbox "By gosh, a double-click!"

End Select

End Select

End Sub

The event string returned from the control and placed into the callback field contains the name of the event, followed by a comma-delimited list of any parameters associated with that event. Following this data is a vertical bar character (|) and finally a date/time value, which insures that your Outlook forms CustomProperty_Change event is fired. You should strip off and ignore all characters from the vertical bar to the end of the string (in the code sample above, the GetPropertyValue method of the Outlook Extensions Library performs this trim operation).

Event Cancellation Note:

Some VSFlexGrid events provide a Cancel parameter, which, when set to True, allows the developer to cancel an event before it occurs. Due to the lack of built-in support for events by the Outlook forms engine, and the way in which we therefore fire events via the Callback Field, it is not possible to provide support for the Cancel parameter or canceling events in this manner.

OLEventTriggerLevel

This property defines the categories of events that will be returned from the OLGrid control back to your Outlook application via the callback field. See the list of events above to determine which category a particular event belongs to.

The possible values for this property are:

1-OlEvtAllEvents

2-OlEvtNoMouseMoveEvents

3-OlEvtActiveUserEventsOnly

4-OlEvtUserEditingOnly

5-OlEvtNoEvents (default)

It is strongly recommended that you do not use the OlEventAllEvents setting unless you absolutely require notification of Mouse Move events, as this setting uses up a large amount of system resources.

It is important to note that when the grid updates the callback field with an event notification, this causes the form to be dirty; that is, Outlook now treats this form as having modified data. The OlUserEditingOnly setting is thus useful in preventing erroneous firing of the Do you want to save changes? dialog when exiting the Outlook form.

FormatString

OlGrid provides an enhanced version of this VSFlex property. In OlGrid, the list of text segments can be separated by a comma delimiter (in VSFlex, only a vertical bar character (|) is allowed as a segment delimiter).

FormatWidth

This property allows you to define column widths for a series of columns at one time. For example:

OGrid.FormatWidth = 400,400,750,670

You can bypass setting the width for any column by not providing any width for that column; for example:

OGrid.FormatWidth = ,,900,,500

The above example sets the width of column 3 to 900 and the width of column 5 to 500; no other column widths are affected.

You can use either a comma or a vertical bar character (|) as the delimiter between column widths.

CellPicture

This property replaces the VSFlex CellPicture property. To insert a picture into a grid cell, place an Image control on your Outlook form; place a picture into the Image control. Then set this property to the name of the Image control. Ex:

OGrid.Row = 3

OGrid.Col = 0

OGrid.CellPicture = picSmileyFace

To clear a cell picture, set this property to a null string. Ex:

OGrid.Row = 3

OGrid.Col = 0

OGrid.CellPicture =

Version

This property returns the current version number of the OlGrid OCX. The format is two digits each for major, minor and revision. For example: 020411 represents version 2.4.11


Grid Methods

VSFlex7L Methods Supported

The following VSFlex7L methods are supported by the OlGrid control. Please refer to the accompanying VSFlex documentation for details on using these methods.

AboutBox

AddItem

AutoSize

CellBorder

Clear

EditCell

GetMergedRange

LoadGrid

Outline

RemoveItem

SaveGrid

Select this method is available as the OlGrid SelectCells method

ShowCell

Subtotal

New and Enhanced OlGrid Methods

SelectCells

This method corresponds to the Select method of the VSFlex grid control.

ArrayToGrid

Loads a series of values from an array into rows and columns in an OlGrid control.

OGrid.ArrayToGrid(Array, [StartRow], [StartCol], [EndRow],                                         [EndCol], [OptionFlags])

Array: Variant array containing the data to load

StartRow: Optional starting row number for the load. Default=first row (Row 0)

StartCol: Optional starting column number for the load. Default=first column (Column 0)

EndRow: Optional ending row number for the load. Default=last row

EndCol: Optional ending column number for the load. Default=last column

OptionFlags:Optional flags (see below)

The OptionFlags parameter allows you to easily specify common load patterns without having to explicitly identify exact row and column numbers. Possible values are:

OlArraySkipFixedCells Skip any rows that have been defined as fixed

OlArraySkipSubtotals Skip any rows that have been defined as subtotals

GridToArray

Returns a series of values from rows and columns in an OlGrid control to an array.

Array = OGrid.GridToArray([StartRow], [StartCol], [EndRow], [EndCol], [OptionFlags])

Array: Return variant array

StartRow: Optional starting row number for the retrieval. Default=first row (Row 0)

StartCol: Optional starting column number for the retrieval. Default=first column (Column 0)

EndRow: Optional ending row number for the retrieval. Default=last row

EndCol: Optional ending column number for the retrieval. Default=last column

OptionFlags:Optional flags (see below)

The OptionFlags parameter allows you to easily specify common load patterns without having to explicitly identify exact row and column numbers. Possible values are:

OlArraySkipFixedCells Skip any rows that have been defined as fixed

OlArraySkipSubtotals Skip any rows that have been defined as subtotals

AddItem

VSFlex allows you to specify multiple columns of data when adding items to the grid via the AddItem method. To do this, you must use a Tab character (i.e. Chr(9)) as a column delimiter. OlGrid's AddItem method supports the use of either a Tab character or a vertical bar (i.e. | ) as a column delimiter. This allows for a much simpler code syntax for most uses.


Grid Events

VSFlex7L Events Supported

The following VSFlex7L events are supported by the OlGrid control. Please refer to the accompanying VSFlex documentation for details on these events.

EVENT

CALLBACK TRIGGER LEVEL

AfterCellChange

AfterEdit

AfterMoveColumn OlEvtActiveUserEventsOnly

AfterMoveRow OlEvtActiveUserEventsOnly

AfterRowColChange OlEvtNoMouseMoveEvents

AfterScroll OlEvtNoMouseMoveEvents

AfterSort OlEvtActiveUserEventsOnly

AfterUserFreeze OlEvtNoMouseMoveEvents

AfterUserResize OlEvtActiveUserEventsOnly

BeforeCellChange OlEvtNoMouseMoveEvents

BeforeEdit OlEvtActiveUserEventsOnly

BeforeMoveColumn OlEvtActiveUserEventsOnly

BeforeMoveRow OlEvtActiveUserEventsOnly

BeforeRowColChange OlEvtNoMouseMoveEvents

BeforeScroll OlEvtNoMouseMoveEvents

BeforeScrollTip OlEvtNoMouseMoveEvents

BeforeSort OlEvtActiveUserEventsOnly

BeforeUserResize OlEvtActiveUserEventsOnly

CellButtonClick OlEvtActiveUserEventsOnly

CellChanged OlEvtNoMouseMoveEvents

ChangeEdit OlEvtUserEditingOnly

Click OlEvtActiveUserEventsOnly

Compare OlEvtNoMouseMoveEvents

DblClick OlEvtActiveUserEventsOnly

EnterCell OlEvtNoMouseMoveEvents

KeyDown OlEvtActiveUserEventsOnly

KeyPress OlEvtActiveUserEventsOnly

KeyUp OlEvtActiveUserEventsOnly

LeaveCell OlEvtNoMouseMoveEvents

MouseDown OlEvtActiveUserEventsOnly

MouseMove OlEvtAllEvents

MouseUp OlEvtActiveUserEventsOnly

RowColChange OlEvtNoMouseMoveEvents

SelChange OlEvtNoMouseMoveEvents

StartEdit OlEvtUserEditingOnly

ValidateEdit OlEvtUserEditingOnly

OlEvtNoMouseMoveEvents

OlEvtUserEditingOnly

Because the Outlook forms model does not provide support for ActiveX events, OlGrid implements event notification via a separate callback field on the Outlook form. See the OlCallBackField section below for details.

The following events were supported by OlGrid1 in the initial release of OEL, but are no longer supported. Most of these have been superceded by new events in OlGrid2.

UserResized

Scroll

Collapsed

KeyDownEdit

KeyPressEdit

KeyUpEdit

Error


Usage Notes

OlGrid: Usage Notes

Errors

In order for OlGrid to function properly on an Outlook form, two ActiveX components must be correctly installed and registered on a users PC: OlGrid.ocx and VSFlex7L.ocx. If either of these controls are not present on the users machine, or are not correctly registered in the Windows registry, an Outlook error message will occur. Following are the error messages and their causes:

"Could not load an object because it is not available on this machine"

This message appears if OlGrid.ocx is missing or not properly registered on the users PC. The Outlook item will open, but all OlGrid controls will be missing from the displayed form.

"Cant open this item"

This message is displayed if VSFlex7L.ocx is missing or not properly registered on the users PC, and the form being opened contains an OlGrid control(s) on its initial page.. The Outlook item will fail to open.

"The operation failed"

This message is displayed if VSFlex7L.ocx is missing or not properly registered on the users PC, and the form being opened contains an OlGrid control(s) on subsequent pages, but not on the initial form page. The Outlook item will open, but all OlGrid controls will be missing from the displayed form.

Pasting an OlGrid control

When cutting-and-pasting an OlGrid control onto a form, or deleting an old OlGrid version and inserting a new version on the form, you may find that other controls on the form either lose their field bindings, or their field bindings become scrambled such that controls are bound to the wrong fields.

So, whenever you are updating to a new version of the Grid on a form, or cutting/copying and pasting an OlGrid, please be sure to check the remaining form controls to ensure that they properly bound.

Note that this behavior can also occur for other controls aside from OlGrid, so be careful when performing the above-mentioned operations. The issue appears to be related to one mentioned in the Microsoft Knowledgebase; see article Q195233 for more information.


Intro

Introduction: Code Samples

Some of the examples included here, while some are not necessarily complete modules, are presented to help illustrate the capabilities of our products and of Outlook. Some examples are presented in a bare-minimum fashion and may require additional error handling to be used in a full user situation.

You can copy the code from these samples and paste into your form but you will need to run them through the Help Code converter first. The included converter (HelpCodeConvert.EXE) program will reformat the code so it is suitable for use in Outlook.

Converter Instructions:

1) Select the code you want in this Help file to use and select Copy.

2) Press the "Convert Clipboard" button.

This converts the HTML text in the clipboard to regular text that can be used and then places it back into the clipboard.

3) Go into Outlook and then paste it in.

If you have some useful examples that could be included in this section, we would very much appreciate them. Please send any errors you may find or new ideas to Support@TeamScope.com.


Updating the Subject

Sometimes it is desirable to have a user specify the subject or change the subject of an item. The risks in doing this are that a user may not pick a unique subject which will render any hyperlinks inoperable. Furthermore, changing the subject after any hyperlinks have been established will render these inoperable. The code below give you some level of tradeoff if user control of the subject is required.

Sub Item_PropertyChange(ByVal Name)

If Name="Subject" Then

t=oLib.History.GetInitialValue("Subject")

If Item.Subject<>t And t<>"" Then

r=Msgbox("Warning: Changing the subject will have potential issues. Do you wish to change it?",vbImportant+vbYesNo)

If r=vbYes Then

Item.Subject=Item.Subject+Space(Second(Now))+"."

Else

Item.Subject=t

End If

Else

Item.Subject=Item.Subject+Space(Second(Now))+"."

End If

If Item.EntryID="" Then

Item.Save

oLib.SetLock "Locks" ' because the item is now visible to other users you need to obtain a lock.

If oLib.LockState<>"" Then MsgBox oLib.LockState

End If

End If

End Sub


GAL lookup

It is very common to want to be able to programmatically access recipients from the GAL. In order for this code to work your clients must have CDO installed.

Function SelectUser(tCaption)

On Error Resume Next

Set oSess = CreateObject("MAPI.Session") ' The user must have CDO installed!

oSess.Logon "", "", False, False, 0 ' use the current session

Set oRecipColl = oSess.AddressBook(,tCaption,False,True,1,"User")

If Err=0 Then

Set SelectUser=oRecipColl(1)

End If

End Function


Creating linked items

Creating new items programmatically that are linked through the contact links collection is a common need. What is important to understand is that before a link can be established the item you are linking to must be saved first.

In this example we are creating a employee contact that is linked to its parent company item.

Sub cmdNewEmployee_click()

Set oEmployeeFolder=oLib.GetFolderFromURL("\some folder path\Employees")

Set oEmployee=oEmployeeFolder.Items.Add("IPM.Contact.MyEmployee")

oEmployee.CompanyName=Item.CompanyName

oEmployee.Links.Add Item

t=InputBox ("Enter new employee name") ' must first enter new name before the new item is saved

oEmployee.FullName=t

oEmployee.Save ' new item must be saved before it can be linked back

Item.Links.Add oEmployee

oEmployee.Display

End Sub

It is possible that the once the new linked item is created the name of the contact could change. In this case you may will want to make use of the UpdateLinks function.


Linking with Excel attachment

It is possible to have Outlook obtain a reference to the Excel attachment and thus be able to communicate and control it.

Works like this:

  • Pressing the “Run Excel” button saves the attachment to a temp XLS file

  • This temp file is then loaded into a newly created Excel object

  • The form monitors the Excel object on a periodic basis by using the OEL timer functions

  • Changes to any part of the Excel object are visible as shown in Cell 1,1 and Cell 1,2 for instance

  • If the Excel object goes away then it must be because the user saved the changes and closed the file.

  • When this occurs the temp XLS file is used to replace the existing attachment

You will need to test and add in error handling as needed. Only works properly if Excel is not running to start with.

Dim oLib ' As OutlookExtensions.Library

Dim oExcel ' As Excel.Application

Dim tFile ' As String

Dim fSaveStat ' As Boolean

Function Item_Open()

Set oLib=Application.CreateObject("OutlookExtensions.Library")

oLib.Support.TimerField="ExcelCheck"

End Function

Sub cmdRunExcel_Click()

On Error Resume Next ' needed incase file does not exist

tFile = "c:\Temp\" + Item.Attachments.Item(1).FileName

Kill tFile

On Error GoTo 0

Item.Attachments.Item(1).SaveAsFile (tFile) ' Export the file from Outlook

Set oExcel = CreateObject("Excel.Application")

oExcel.Application.Workbooks.Open tFile ' Import the file into Excel

oExcel.Visible = True

oLib.Support.TimerInterval=1 ' Start polling loop 1 sec.

End Sub

Sub Item_PropertyChange(ByVal Name)

If Name="ExcelCheck" Then ' Companies is used as the callback event field

On Error Resume Next ' Important - Need this for check of Excel going away

Err.Clear

fSaveStat = oExcel.ActiveWorkbook.Saved ' hold the last state of the Excel Saved flag

If oExcel.Application.Workbooks.Count >= 1 Then

Item.BillingInformation = oExcel.Cells(1, 1)

Item.Mileage = oExcel.Cells(2, 1)

Else ' Excel object has been closed

oLib.Support.TimerInterval=0

Set oExcel = Nothing

If fSaveStat = True Then

Set oAttach=Item.Attachments(1)

oAttach.Delete ' Remove the old file

Item.Attachments.Add tFile ' Add back the new file

End If

End If

End If

End Sub


Saving data in the body

If you need to store a large amount of information in an Outlook object then the best place is either an attachment or the body. Attachments have a considerable amount of overhead associated with them were as the message body does not. The example below uses the body of a message to store a large matrix of data that is loaded into the OlGrid control. In the example below the code is given for both cases that allow you to leave the matrix in the body or remove it as the form is opened.

Item_Open event ...

If Item.Body="" Then Item.Body=vbcrlf+vbcrlf+vbcrlf+vbcrlf+vbcrlf+vbcrlf+"[GridData]"

pData=Instr(Item.Body,"[GridData]") ' Locate the data

If pData > 0 Then

ta=Mid(Item.Body,pData+12) ' Skip over the [GridData] and <CR>

va=oLib.Support.TextToArray(ta)

Item.Body=Left(Item.Body,pData-1) ' Include this line if you want to remove the data for the user

End If

If IsArray(va) then

oGrid.ArrayToGrid va,1,0

End If

Item_Write event ...

va=oGrid.GridToArray(1,0)

' If you left the data in the body then use this code replace the data

pData=Instr(Item.Body,"[GridData]")-1

Item.Body=Left(Item.Body,pData)+"[GridData]"+vbCrLf+oLib.Support.ArrayToText(va)\

- or -

' If you removed the data in the body then use this code to add the data back

Item.Body=Item.Body+"[GridData]"+vbCrLf+oLib.Support.ArrayToText(va)


Pasting data from Excel

This code uses OEL clipboard and TextToArray functions to allow a user to paste data from Excel into an array which can be used by your Outlook form.

Sub cmdPaste_Click()

t=oLib.Support.ClipboardText

va=oLib.Support.TextToArray(t,chr(9))

If IsArray(va) then

oGrid.ArrayToGrid va,1,1

Else

Msgbox "No grid data found in clipboard",vbExclamation

End If

End Sub


Printing the Grid

Printing the Grid & Body

Below is the typical code for printing a form that has an OlGrid control and the notes (body) field which both require special handling. The page that has been laid out for printing is called "Print" and it has a grid called "grdPrint" and a text control called "txtPrint".

Sub cmdPrintForm_Click()

Item.GetInspector.ShowFormPage("Print") ' un-hide print page tab - required if tab was hidden

Set oGridToPrint=Item.GetInspector.ModifiedFormPages("Print").Controls("grdPrint")

oLib.CopyGridProperties oGrid, oGridToPrint

oGridToPrint.Rows=21 ' You may have room for many more rows on a printed form

' Because of the different DPI it is common to readjust the column widths for printing

oGridToPrint.FormatWidth="400|0|1500|4500|1000|900|1100|1100|700"

'Copy the body to a multi-line text control for printing

Item.GetInspector.ModifiedFormPages("Print").Controls("txtPrint").Text=Item.Body

oLib.PrintForm "Print"

Item.GetInspector.HideFormPage("Print") ' hide tab again.

End Sub


Grid - Read only Column

The has property definable ready only columns by setting the "FixedCols" property. However, these columns can only be defined on the left-hand side and cannot be defined in the middle of your grid working area.

A simple solution is to use the Grids "BeforeEdit" event to force the user away from the column. This same code will work for making read only rows and cells if necessary.

Say you want to keep users out of column 7 but column 8 is ok.

If PropVal="BeforeEdit" Then

If oGrid.Col=7 Then

oGrid.Col=8

End If

End If


Item Sync Example

This example users the functions of the Sync object to add private folder sync to a Task or Appointment item.

Example 1: User mode (peer-to-peer) -- each specified user must have delegate access

This example assumes you have a form page called "Private Sync" with Grid control called "grdPublish", a command button called "cmdProcess" and a check box called "chkForce". To provide a easy way to delete the item from the first page a action called "Delete Shared Appointment" is used. The form must also have a keywords (text type) data field hidden on the form in this case called "PubDataArray"

'Declare global variables

Dim oLib ' Outlook Extension Library object

Dim oPage ' hold reference to the first form page object

Dim grdPub ' the Grid control which displays sync status

'################################### Init ####################################

Function Item_Open()

Set oLib = Application.CreateObject("OutlookExtensions.Library")

Set oPage = Item.GetInspector.ModifiedFormPages("Private Sync")

Set grdPub=oPage.Controls("grdPub")

oLib.ItemSync.Setup "User A=1; User B=1; User C=0", "PubDataArray", grdPublish

End Function

'################################### Form (Button) Events ####################

Sub cmdProcess_Click()

chkForceAdd=oPage.Controls("chkForce")

oLib.ItemSync.Process "PubDataArray", grdPublish,,chkForceAdd

End Sub

Function Item_CustomAction(ByVal Action, ByVal NewItem)

If Action="Delete Shared Appointment" Then

oLib.ItemSync.Remove("PubDataArray")

Item.Delete

Item_CustomAction=False

End If

End Function

'################################### CloseUp #################################

Function Item_Write()

oLib.ItemSync.Process "PubDataArray", grdPublish

End Function

Example 2: Agent mode (client-server) -- only the Agent mailbox must have delegate access

In this example there is no UI grid control. This example requires the TeamWork™ Workflow Agent to be setup and operational. The mailbox of the workflow agent is called "Workflow Agent"

Dim oLib

'################################### Init ####################################

Function Item_Open()

' The SetX line below is needed because of strange behavior a non-modified

' 1st page form being opened by a external process... the workflow agent

Set X=Item.GetInspector.ModifiedFormPages("Private Sync")

Set oLib = Application.CreateObject("OutlookExtensions.Library")

oLib.ItemSync.Setup "User A=1; User B=1; User C=0", "PubDataArray"

End Function

'################################### CloseUp ################################

Function Item_Write() ' Called first when user selects 'Save' or 'Save and Close'

If IsObject(oLib) Then

Set oSyncNotice=Application.CreateItem(0)

oSyncNotice.To="Workflow Agent"

oSyncNotice.Subject="Item Sync "+ Item.Subject

oSyncNotice.BillingInformation=Item.EntryID

oSyncNotice.Mileage="PubDataArray"

oSyncNotice.Categories=1 ' Use a hyperlink

oSyncNotice.Send

End If

End Function


Introduction

Introduction - Interfacing to the Enterprise

Interfacing to your existing environment and the external world is crucial to the successful implementation of many enterprise workflow applications. There are two typical barriers to integrating with Exchange:

  • No ODBC: Because Outlook and the underlying Exchange store technology do not natively support standard interfaces such as ODBC

  • Security: Most organizations for good reason have firewalls to keep unauthorized users out.

OEL and TeamWorkÔ comes with a number of tools that make the job easy. The selection of the correct tool and approach depends on many factors. Understanding the relationship and scope of these interfaces is important. There are three basic levels of interfaces:

External Users

Any simple mail message, internal or external, that can be sent to the Agent mailbox. The Agent’s Bridge function can convert the properly formatted body of an SMTP message into a true MAPI workflow posting. The StatusNotify option provides workflow status notification to any user, internal or external. For instance, you can use this feature to allow your external vendors or customers to start workflows, and receive status on internal workflows, automatically.

You can also use the Watch Dog system to monitor the status of workflow agent because it uses SMTP.

Internal Users

Users must be able to log into NT and have an Exchange (E-mail) account. Knowledge of MAPI (CDO or Outlook) programming is required. Can perform any operation directly against the data in any workflow item, because the system is 100% MAPI-based.

Internal users also can view workflow data by using Exchange's public folder views or by monitoring the workflow stats web page.

Direct Users

Required to have the Outlook Extensions Library installed. Workflow Analyzer provides sophisticated workflow performance analysis and automatic export of all data to an ODBC MS Access database. The Message Data Publisher provides a tool to keep any message data in sync with an ODBC data source. You can call OEL from any process to take advantage of various functions


Using MAPI

Because the workflow is 100% Outlook (MAPI) based, any MAPI process that has appropriate access to the workflow folder can read, write and update any workflow item. Below are some basic examples of creating new items and reading data from items in an Exchange Public Folder.

Object model notes

Please note that there are two high-level object models that support Exchange/MAPI programming: CDO (Collaboration Data Objects) and Outlook. The CDO object model, also sometimes referred to by its older name of Active Messaging, is the more traditional "server" process. The Outlook object model is considered a "client side only" tool. Although it is possible – for the most part – to create new items using the CDO object model, it is considerably more difficult than using the Outlook object model directly. The only major downside to using the Outlook object model for generating and reading message items is that it requires that an Outlook client be installed and running. The following examples use the Outlook object model and Visual Basic.

NOTE: Make sure that you have "Microsoft Outlook 8.0 Object Library" (Outlook 97/98) or “Microsoft Outlook 9.0 Object Library” (Outlook 2000) set in your project references.

Creating an Item

' Define object variables

Dim oApplication As New Outlook.Application

Dim oPubFolder As Outlook.MAPIFolder

Dim oFolder As Outlook.MAPIFolder

Dim oTask As Outlook.TaskItem

Dim oField As Object

' Set folder to target location

Set oPubFolder = oApplication.GetNamespace("MAPI").Folders("Public Folders")

Set oFolder = oPubFolder.Folders("All Public Folders").Folders("Sub Folder").Folders("My Workflow Folder")

' Create a new item with the correct message class

Set oTask = oFolder.Items.Add("IPM.Task.MyWorkflowClass")

' Update built-in default fields

oTask.Subject = "New Workflow Task Item"

oTask.DueDate = "10 Nov 2000"

' Add user-defined custom fields with the correct type

Set oField = oTask.UserProperties.Add("Customer Name", olText)

oField = "Jack Smith"

' You can even add some event status data for the workflow to pick up

Set oField = oTask.UserProperties.Add("EventStatus", olKeywords)

oField = "1: First Step; User A; First Event; 10 Nov 2000 8:32 am"

' Save the new Task item in the folder

oTask.Save

Reading items in a collection

[This example assumes the oFolder object is assigned as shown in the previous code example]

Dim oItems As Outlook.Items, oItem As Object

Dim v As Variant, t As String, i As Integer

' Limit the item collection of the folder to the item(s) you want by using the Restrict method

Set oItems = oFolder.Items.Restrict("[DueDate]='10 Nov 2000' AND [Customer Name]='Jack Smith'")

t = vbNullString

For Each oItem In oItems

t = t & oItem.Subject & vbCrLf

t = t & oItem.DueDate & vbCrLf

t = t & oItem.UserProperties("CustomerName") & vbCrLf

' The EventStatus field is a Keywords array field and must be sent to a variant

v = oItem.UserProperties("EventStatus")

For i = 0 To UBound(v)

t = t & v(i) & "; "

Next i

MsgBox t

Next

Notes

If you use a process to post workflow items on behalf of other users (mailboxes), the items will be shown as coming from the process’ mailbox according to native MAPI properties. The Originator property allows you to “pass though” the intended originator by setting the "Companies" built-in property to the sender address. When you do this, you must precede the address with "~~~" so the system identifies this as a special Originator value, in case the field is also being used for another purpose.

Note that there are a minimum number of fields that must be defined when creating a workflow item using a MAPI process:

MessageClass Must match the published form’s message class

Subject Should be unique

EventField Must be created as a keyword data type (olKeywords)

StatusField Must be created as a text data type (olText)

The EventField and the StatusField can be blank, but they must be defined ( Item.UserProperties.Add ) in order for the Workflow Agent to successfully process them. You do not necessarily need to define any other fields, because when a user opens a form using Outlook, the system automatically takes care of defining all of the other fields that are specified in your published custom form.

Reading or creating new items is not problematic; however, updating existing items must be done with some care. Exchange does not provide any form of a locking mechanism. If a user has an item open and is updating it, and a process comes along and updates and saves the item, Exchange will generate a conflict (Exchange v5.5) or, worse, will disable the item from then being saved by the user. If you need to do updates to existing workflow items reliably, you need to check for the existence of TeamWorkÔ locks as described by the Outlook Extension Library’s "SetLock", "CheckLock" and "LockState" methods.


Calling from Outside Outlook

Calling the Library from Outside Outlook

Although the Outlook Extensions Library is designed primarily to be called from within an Outlook item's script code, it can be called from outside of an Outlook item with limited functionality. Many of the functions only apply when they are called from within an Outlook item. However, some of the functions that are available can be of value if you are going to write a MAPI process that interfaces with TeamWorkÔ workflow items and configuration messages. For instance, the Workflow Analyzer makes extensive use of the Extensions Library to easily accomplish its necessary tasks. Below is a list of the available functions which can be used outside of Outlook.

Available for use

DisplayErrors

CurrentItem

GetFolderFromURL (Navigate)

GetItemFromURL

GetURL

HomeFolder

ItemProperties

License

Version

CloseLibrary

Suport.TextToArray

Support.ArrayToText

Support.ClipboardText

Support.FormatText

Support.BeepTone

Support.RunShell

Support.TimerField

Support.TimerInterval

Support.SortArray

Config.SetFolder

Config.ReadMsgEntry

Config.ReadMsgEntryVar

Config.WriteMsgEntry

Config.ReadMsgData

Config.ReadMsgSection

Config.ReadMsgSectionList

Config.DeleteMsgSection

Config.AddMsgSection

Config.MsgEntry

Tech Note

Because the Extensions Library must have a reference to an Outlook message item to operate, you will need to provide the library with a item reference by using the CurrentItem property. Note that you must always close the library via the CloseLibrary method. Using functions that are not listed above will either do nothing or will cause unpredictable results.

Example

The following Visual Basic example shows how to use the OEL to navigate to a folder and list the steps in a TeamWorkÔ workflow template.

Dim oLib As New OutlookExtensions.Library

Dim oFolder As Outlook.MAPIFolder

Dim oItem As Outlook.PostItem

Dim oApp As New Outlook.Application

Dim v As Variant

Set oItem = oApp.CreateItem(olPostItem)

Set oLib.CurrentItem=oItem

oLib.DisplayErrors = True

oLib.Config.SetFolder("\\Public Folders\All Public Folders\Workflow folder\Config Folder")

v = oLib.Config.ReadMsgSectionList("Workflow Configuration",False)

MsgBox oLib.Support.ArrayToText(v, vbCrLf)

oLib.CloseLibrary

Note that because the above example uses early binding you will need to make sure that your application has references to both the Outlook (Microsoft Outlook x.0 Object Library) and OEL (TeamScope Extensions Library for Outlook).


Disclaimer

Disclaimer:

TEAMSCOPE SOFTWARE INCORPORATED AND ITS OWNERS DISCLAIM ALL WARRANTIES EITHER EXPRESS OR IMPLIED.

SHOULD THIS PROGRAM PROVE DEFECTIVE, THE PURCHASER ASSUMES THE RISK OF PAYING THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR, OR CONNECTION AND ANY INCIDENTAL OR CONSEQUENTIAL DAMAGES. IN NO EVENT WILL TEAMSCOPE SOFTWARE INC BE LIABLE FOR ANY DAMAGES WHATSOEVER ARISING OUT OF THE USE OR THE INABILITY TO USE THIS PRODUCT.

RESALE OF THIS PRODUCT IS NOT PERMITTED - TO USE THIS PRODUCT BEYOND ITS TRIAL PERIOD, YOU MUST OBTAIN PROPER LICENSE REGISTRATION.

USE OF THIS PRODUCT FOR ANY PERIOD OF TIME CONSTITUTES YOUR ACCEPTANCE OF THIS AGREEMENT AND SUBJECTS YOU TO ITS CONTESTS.

USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO RESTRICTIONS AS SET FORTH IN SUBDIVISION (b)(3)(ii) OF THE RIGHTS IN TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT 52.227-7013.

THE FEATURES, PERFORMANCE, COST OF THE PRODUCT, OR THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT NOTICE AND DOES NOT REPRESENT A COMMITMENT ON THE PART OF THE AUTHOR/OWNER OR TEAMSCOPE SOFTWARE INC.

THE INFORMATION PROVIDED IS FOR INFORMATIONAL PURPOSES ONLY AND TEAMSCOPE SOFTWARE INC OR ITS SUPPLIERS MAKE NO WARRANTIES, EITHER EXPRESSED OR IMPLIED, AS TO THE ACCURACY OF SUCH INFORMATION OR ITS FITNESS TO BE USED FOR YOUR PARTICULAR PURPOSE. THE ENTIRE RISK OF THE USE OF, OR THE RESULTS FROM THE USE OF THIS INFORMATION REMAINS WITH YOU.

Copyright:

The Outlook Extensions Library and TaamWork are copyrighted Ó1999-2001 by TeamScope Software, Inc. The information in this document cannot be reproduced or transmitted, for any purpose, without the express written permission of TeamScope Software, Inc.


Config Field Redirection

Entries in a configuration file can be redirected back to live values on the current Outlook form. This feature provide a powerful capability to add template based functionality to your forms without having to write code. This also add flexibility to your forms because you can make changes to the configuration file without having to re-publish your forms. You can take advantage of this capability in your forms by using the config object's ReadMsgEntryVar function.

This capability is used extensively in the TeamWorkÔ workflow product. Field values in a TeamWorkÔ workflow template item can be easily redirected (See: VAR dialog) to use live data values pulled from the actual workflow item. This is a powerful tool that allows for significant customization of any workflow template setup with a minimal amount of effort. It also provides an ad-hoc capability to modify just about any component of a workflow, including the flow (i.e. branching) itself.

Example:

For example, the "StatusText" template field can be extended to generate a whole custom return message based on field data.

StatusText=Your request of ${{Total Amount}} for {{CustomerName}} is currently being reviewed in {{Sub Region}}<cr><cr>Thank you for your order.

Where TotalAmount, CustomerName, and Sub Region are data fields on the workflow form, and where for a particular item {{Total Amount}} = "34", {{CustomerName}} = "Bob Jones" and {{Sub Region}} = "Switzerland", the following status message would be produced:

Your request of $34 for Bob Jones is currently being reviewed in Switzerland.

Thank you for your order.

Notes:

  • Virtually any workflow field can be redirected.

  • Make sure the data in the field is valid before the step is activated or function is called.

  • The field redirection operation can be recursive, in that a field can contain further {{field}} redirections.

  • Some fields in the workflow cannot be redirected. Redirecting these fields will cause unpredictable results. Do not redirect any of the fields in the [SetupInfo] section, or the "Type" field in any [Step] section.

  • The optional "CaseField" is already always redirected when used, and does not require the double brackets.

Array - Grid support:

You can even redirect to specific values in a keyword field. For example you can read individual values from a Grid control because it is actually bound to a keyword data field.

For instance say you have a grid as shown below that is bound to a keyword field called "Keep Advised"

CustomsDate={{Keep Advised, U.S. Customs+1}}

This config keys says find a multi-valued (keyword) field called "Keep Advised" on the form. Then search for the value "U.S. Customs" and when found return the next (+1) column's data. Thus, when this config item is queried it would return the value of "22-Aug-00". Note that the value searches are not case sensitive and trim off any leading or trailing spaces.

Config item redirection

There is also a third form of redirection that you can use to redirect to other configuration items. This form of redirection does not look at a field on the current item, but looks to data contained in items stored in the current configuration folder. You can think of this feature as a type of include function. Note that Config Item redirection is performed after item field redirection. This function in effect calls the Config object ReadMsgEntry function of the library.

Syntax: <<Subject, Section, Key>>

For instance, you could use this function to display different instructions to the user by using item field redirection to specify the config item location. This allows one to place textual information outside of the form for ease of maintenance and documentation.


Off-line & Distributed Operation

Outlook and Exchange provide the basic functionality to operate while disconnected from the Exchange server. Exchange also supports a highly distributed information store architecture that allows you to have your workflow forms span your entire E-mail network. With this freedom, however, come some complications and issues that you must be aware of before embarking on a off-line or distributed strategy.

Outlook issues

The main issue is that referencing a parent folder object in Outlook does not function properly while working off-line. To get around this issue, you must use the direct Entry ID and Store ID for the folder when using the SetFolder method. If you do not use the EntryID and StoreID while off-line, you will be unable to link to them from other folders.

Lib.Config.SetFolder("down-path", EntryID, StoreID)

Furthermore, because of the same issue, while you are operating off-line, you cannot reference any up ".." paths in the GetFolderFromURL (Navigate) function. You can use normal down paths and absolute navigation as you would working online.

Outlook links

Outlook text hyperlinks do not work while running off-line. This is because of the simple reason that the named path is different. Just be careful and keep this limitation in mind. This in particular impacts the usefulness of the GetURL function. The libraries GetFolderFromURL and GetItemFromURL both detect an off-line case and will properly search the off-line favorites successfully but Outlook itself cannot use its own hyperlinks!

The solution to this situation is to always use GUID-based links. These links will work on-line or off-line. In fact, they will even work if the folder is renamed or moved, so long as it remains in the same information store. The TeamWorkÔ workflow library can use of GUID-based links for all of its workflow processing (See: Show Links As). For your own code, you can make use of Outlook's GetFolderFromID function or the Attachments.Add olByRef option to add links to a message.

Favorites

Adding a Public Folder to your Favorites and setting the synchronization property to "When Online or Off- line" allows the Public Folder to be available when disconnected. If you wish to make use of off-line operation, you must replicate in your Favorites all the necessary data and support folders that make up your collaboration system.

Some folders must be replicated, while others must not. In particular:

· Do replicate all the necessary supporting folders for your workflow form. In particular, be sure to replicate the defined configuration folder.

· Do not replicate any Locking folders! This is unnecessary and in fact will potentially cause complications.

Item size

Each item in Outlook is potentially limited in size. The total text (character) size of all native fields cannot typically exceed 8k. Similarly, the total text (character) size of all custom fields cannot exceed an additional 8k. The size of the message body can be considerable larger, and attachments are basically unlimited in size. If your form exceeds these limits, it will fail to synchronize. This is a fairly large amount of text, but should be taken into consideration.

One effective work around if your form is large is to store the data array in the body of the item by making direct use of the TextToArray and ArrayToText functions.

OST replication failure

If any element of an Outlook Keywords data type field is blank (null), synchronization will fail. Note that all Workflow items make use of Outlook Keywords data fields to store the Event History, but this data array should never contain any blank values. If you make use of a Keywords field, make sure that you fill all the values with some valid character. If this is an issue, you can alternatively use a standard text field with delimiters by making use of the TextToArray and ArrayToText methods of the Extensions Library.

Store replication

Information store replication in Exchange is a very important topic to understand. There are basically two types of information replication; off-line user and server-to-server, both of which have the same set of complications that must be carefully considered.

· Off-line user: "Replication" period is controlled by when the user logs back in and syncs.

· Server-to-server: Replication period can be controlled by the administrator and available network bandwidth.

The first issue to understand is that the OELs locking solution will only work 100% of the time when all users are connected and hitting the same Locks folder. Locking will work partially across multiple Exchange Public Folders that are being replicated across one or more stores. The quality of the lock will depend on the frequency of the replication. Locking will basically not work at all for users that are working off-line. To work around this limitation, one solution is to have users create lock records when they go off-line; in this way, no one else will be able to modify the locked items while the user is off-line. You can think of this as more of a check-out and check-in system.

The second issue to take into consideration is the period of replication when you define your workflows Duration and NotifyDuration fields. Make sure if you are running across multiple stores or off-line that these times are considerably longer than the replication period.

A final issue to consider when working across multiple Exchange stores is that e-mail sent between users (or processes like the Agent) is typically at a higher priority than that of Public Folder replication. This means that it is entirely possible for the tasks and other notifications to arrive ahead of the actual folder data.

Following are some ideas to minimize these effects:

· Keep steps or even entire workflows separated by their physical stores

· Do not assign a step to a group of users who are on separate folder replicas

· Make sure to have enough time slack to compensate for replication delays

· Train your users to know what to do with a conflict message, in the event that they receive one


Client Registration

Trial period

When you install a trial version of The Outlook Extensions Library, the software is fully functional, but it is registered with a fixed date deadline. Thirty days before the demo license expires, you will start receiving warnings. On the actual deadline date, the library will stop operating. In order to continue using the software at that point, either contact TeamScope Software (Sales@TeamScope.com) to obtain a new temporary registration key, or purchase the product and receive a permanent registration key.

Client Registration

Each client computer that opens an Outlook form which references the OEL library needs to have the registration key installed. The registration process is actually very simple and quick. After purchasing the software, you will receive a REG key file to be installed on each client computer. This can be accomplished either by e-mailing the REG key file to your users with instructions to run it, or you can have the Registry keys placed directly into the users image by whatever means is appropriate for your organization. Keep in mind that if your users are going to be running the registration file, they must have access rights to their computers Registry.

Client REG file

The registration file is a standard Windows REG file; for example:

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\TeamScope\OEL]

"License"=hex:AC,14,A3,64,C6,18,F1,9D,C4,78,2A,7F,80,AD,F1,E5,CE,C2,E1,......

"Checksum"=hex:9F,D5,6C

"Language"="English"

"PublicFolderRoot"="\\\\Public Folders\\All Public Folders"

The License and Checksum keys are encrypted. Any attempt to modify either key will result in the OEL library issuing an error and ceasing to function.

The actual unencrypted license text (see: oLib.License) contains two important parts:

Org=Your Exchange Organization Name

Mode=License level that you have purchased

The Org portion identifies your Exchange organization. Your OEL registration will only work in your organization.

The Mode portion identifies that license you have: Lib: Just OEL, User: TeamWork User mode, Agent: TeamWork Agent

If the last part of the license key contains a date (YYYY-MM-DD) then the library will expire on that date.

The "Language" key is used by the ItemProperties function

The "PublicFolderRoot" is used by the OnLine function


Setup Files

Installing the Library
The Outlook Extensions Library resides on top of a foundation of Outlook and Exchange. Unfortunately, Exchange does not automatically download the necessary DLL and OCX files to the client as it does the basic Outlook form. Each client computer that attempts to run one of these extended forms must have the DLL and OCX files installed locally. The Extensions Library’s CltSetup.exe program will install all of the needed files automatically. You may choose to install the files manually, or to include them as a part of a standard workstation image. Here is a description of the required subsystems and files.

Exchange:
Version 4 or greater. The workflow agent does not utilize event scripting, so any version of Exchange will work.

Outlook:
A full installation of Outlook is necessary. This needs to include the forms development for any user who will be building forms. Outlook must be connected to an Exchange server (running the Exchange service). This library was tested on Outlook client v8.03 and greater.

VBScript:
The VB scripting language must be at minimum of v3.1

VB Runtime:
The library is a based on 32-bit VB 5 (SP2) environment. In order for the OEL to run, VB 5 Service Pack 2 runtime (MSVBVM50.LL) must be installed and functional on the client machine.

Active Messaging/CDO: (Agent computer or persons running the Workflow Designer)
Because of some of the limitations of the Outlook object model, the Extensions Library also makes use of the Active Messaging/CDO object model. The "Microsoft Active Messaging 1.1 Object Library" (which is the file "OLEMSG32.DLL"), or a later version of CDO, is required to be registered on some client computers.

Extensions Library:
This actual Outlook Extensions Library object file must be installed on each client computer to run. The file is called "OlExtend.dll" and should be located in your Windows System directory (System32 for Windows NT). It is automatically installed by OELs Setup program. The file can be manually registered by running RegSvr32 OlExtend.dll from your System directory. This object appears in the registry as "TeamScope Outlook Extensions Library". If you are upgrading the DLL manually without the CltSetup.exe, then you must uninstall the existing library (RegSvr32 /u OlExtend.dll) and then after copying the new DLL, re-register it.

The agent computer does not need the OlExtend.dll; instead it needs to have the OlWfAgnt.dll file installed. This file contains all the functions of the OlExtend.dll, plus all of the necessary workflow agent functions. The agent library appears in the registry as "TeamScope Outlook Workflow Agent".

Outlook Grid Control:
In order to utilize the Outlook Grid custom control, the client and agent computers must have a licensed or OEM copy of VSFlex7L.ocx (version 7.00.041 or later) registered. This file is provided as part of the Outlook Grid custom control. The Outlook Grid control itself is provided by a file called "OlGrid2.ocx". This file appears in the registry as a control called "TeamScope Grid Control for Outlook 2.0". VSFlex7L.ocx must be installed and registered on each computer before OlGrid2.ocx can be operational. . Both of these files are installed automatically as part of the OEL Setup program

Outlook Calendar Control:
The calendar control is called "OlCal2.ocx". The file appears in the registry as a control called "TeamScope Calendar Control for Outlook 2.0". It is also installed automatically by the Setup program.

Note:
When you first install the library you may get an error in the library that states "Create Object: Could not Create Outlook Application Object". This error will go away once you logout or restart your computer.


Publishing Forms

Publishing: "Form Design" folder

Always save your unpublished form in a separate folder than you actual user items "Application Folder". Typically you should have a folder under the main application configuration folder called "Form Design" as shown below.

Save the changes to your form in the "form design" folder. The TeamWork workflow designer needs to find your form in this folder for correct operation

Publish your completed form into your application folder. Never publish the form in this Form Design folder because:

1) It will cause a automatic run error because links will not be correct. You need to be able to select "Disable Macros" when the form is opened.

2) Publishing in more than one place can cause confusion and errors... (see forms corruption below)

Publishing and the Outlook Forms Cache:

Publishing Outlook forms to Exchange is without doubt one of the most problem-prone and frustrating areas for forms developers. Sometimes when publishing a new form version, some clients do not get updated. You can identify a new published form when the brief download dialog box appears. If the form is refusing to be published, try the following steps on the clients computer:

1) Under your Windows directory is a folder called "Forms", which contains a set of sub-folders that hold the local downloaded forms.

2) Shut down Outlook. You must make sure that all Outlook-related processes are completely shut down.

3) Erase the sub-folder that corresponds to your form. If you can't figure out which one corresponds to your form, you can delete them all. Make sure you do not delete the sub-folder called "configs" or the "frmcache.dat" file.

4) Restart Outlook. You may also need to republish the form again.

If you are still having publishing problems, you may need to replace the frmcache.dat file. We have included a clean copy of the frmcache.dat file in our release package. Repeat the above steps, but include in step #3 the deletion of the frmcache.dat file; under Outlook 97 and 98, you will then need to replace the deleted file with the one from our release package (in Outlook 2000, the frmcache.dat file recreates itself). Refer to MSKB article Q232303 for more information on "How the Forms Cache Works".


Outlook Form Issues

Outlook Form Issues (Surviving Outlook forms)

For the most part, Outlook forms and their interaction with Exchange works as planned. Sometimes, however, when developing Outlook forms, things can go wrong and the forms do not work as you might expect them to. This section provides some advice and potential solutions for such issues.

Get the Outlook Script Debugger

Attempting to develop sophisticated Outlook forms using VBScript without a debugger is a very difficult situation. Save yourself a great deal of time and frustration by downloading the script debugger available free from Microsoft: http://msdn.microsoft.com/scripting

Read the available books

There are some books that can provide you with valuable development information. For developers new to Outlook and Exchange, these books are excellent sources of basic information and concepts. Keep in mind that although these books provide general information on many different aspects of Outlook and Exchange development, only the sections that deal directly with Outlook forms and the operation of Exchange Public Folders are directly relevant to forms development and the Extensions Library.

A good source of information about Outlook and Exchange books can be found at:

http://www.slipstick.com/books/dev.htm

In particular, we can suggest that you check out the development books by Randy Byrne, and Sue Mosher.

For more advanced development techniques, many of the available books fall short. We also have an extensive Outlook development course available, which discusses both the "fine art" and the "dirty secrets" of developing in Outlook. This material was developed over the years from the hands-on development of many Outlook-based systems. Please visit our web site for more information.

Visit some online sources of Outlook help

Some good starting points are:

http://www.microsoft.com/office/outlook/default.htm

http://www.slipstick.com

Field Tips

It is important to make sure, for any new custom field you define, that it is actually present on your custom form, even though you may not need to display or manipulate it directly. An example of this is any of the callback fields that are updated by the Extensions Library or the Workflow Event History field. You can either hide these fields behind other controls, or make then invisible by setting their Visible property to False.

Form One-Off notes:

If your form one-offs it will revert back to its base message class and cause the form definition to be attached to the form. This will result in a item that will be up to 100 times larger in size! Unfortunately there are many operations that can cause a form to one-off.

Changing any property on the item's FormDefinition object at run time will cause the form to one-off.

Changing many properties of a control will also cause a one-off because they change the underlying behavior.

  • MultiLine

  • ReadOnly

  • ListStyle

Also, some functions have been fixed in later versions of Outlook. For instance, in OL2000, hiding a page ("HideFormPage method") does not one-off, while in earlier versions it does.

In this condition, when you save your form you will find that it has one-offed. There is no way to "recover" the size of a one-offed form but you can easily change the message class of the item back to its original value just before the item is saved in the Item_Write event to fix the behavior and avoid the "Enable Macros" warning.

Function Item_Write()

...

Item.MessageClass="IPM.XXXX.MyCustomForm"

...

End Function

There are some operation that the library and TeamWork can be activated which will one-off your form. Fortunately, the TeamWork system provides a "One-Off safe" option which will protect you from unintentionally one-offing your forms.

Misbehaving MessageClass:

Sometimes when a custom form is saved, it reverts back to its default base form Message Class. This can be very annoying because even though the form will usually continue to work properly, it can cause the "Enable Macros" dialog to pop-up when the form is opened. This situation can occur for a number of reasons. The basic solution is to force the Message Class to the desired Message Class in the Item_Write event:

Function Item_Write()

&

Item.MessageClass="IPM.Task.My Message Class"

&

End Function

Copying controls

When cutting-and-pasting controls from one form to another, it is common for the properties of the form you pasted the controls onto to become "confused". These properties will be critical ones, such as Captions, Names and data field Bindings! This will cause your forms to fail if they go unrepaired!

So, whenever you are cutting/copying and pasting controls in Outlook, please be sure to check the remaining form controls to ensure that they properly bound.

The issue appears to be related to one mentioned in the Microsoft Knowledgebase; see article Q195233 for more information.


Outlook Sepcific Functionality

Outlook Version-Specific Functionality

A major design decision was to make our software work with all versions of Outlook. There are a few features that, due to limitations within Outlook, are not available when running some older versions of Outlook. (Note that because our products are primarily client-based, they are not affected by the version of Exchange.)

Following is a list of the features that are not available in all versions of Outlook:

Outlook 2000 Only: OEL

UpdateLinks

Referencing improvements but you can use CurrentItem

Outlook 2000 Only: TeamWork

Private task updating

Journal contact links

Hiding/Disabling entire pages

Outlook 98 and 2000 Only: TeamWork

GUID based hyperlinks


Error Codes

When oLib.DisplayError = True, the Extensions Library will display a user dialog reporting the error and then cancel the error condition. This mode is typically used when developing and testing new forms and workflows. For actual production-level operation, you should consider turning off the error display and handling the error condition within your script. When Lib.DisplayErrors=False, then errors will be returned to the environment. In this case, the Err (Error) object is filled with the following information:

Err.Number format: VBRunTime Code (4 hex digits=8004) + Library Code (4 hex digits)

Example in Hex: 80040F10

List of error codes:

' Base object

ERR_CREATE_OBJECT = &HF00

ERR_NAME_SPACE = &HF01

ERR_CURRENT_ITEM = &HF02

ERR_CURRENT_FOLDER = &HF03

ERR_NAVIGATE = &HF10

ERR_SET_LOCK = &HF20

ERR_CLEAR_LOCK = &HF21

ERR_CHECK_LOCK = &HF22

ERR_PRINT_FORM = &HF25

ERR_ENCRYPT_DATA=&hF04

ERR_PROP_READ = &HF05

ERR_PROP_WRITE = &HF06

ERR_ADDRESS_PROVIDER = &HF27

ERR_REGISTRY_KEYS_INVALID = &HF28

ERR_INVALID_LICENSE = &HF29

' Config object

ERR_SET_CONFIG_FOLDER = &HF30
ERR_READ_CONFIG_MSG = &HF31

ERR_WRITE_CONFIG_MSG = &HF32

ERR_ADD_MSG_SECTION = &HF33

ERR_DELETE_MSG_SECTION = &HF34

' GetItems object

ERR_DISPLAY_CALLBACK = &HF50

' History object

ERR_HISTORY_FIELD = &HF40

' Support object

ERR_SUPPORT = &HF90

ERR_SUPPORT_FORMAT = &HF91

ERR_SUPPORT_TIMER = &HF92

' Workflow object

ERR_WORKFLOW = &HF70

ERR_WORKFLOW_SETUP = &HF71

ERR_WORKFLOW_PROCESS = &HF72

ERR_WORKFLOW_EVENT_HISTORY = &HF73

ERR_WORKFLOW_RESOLVE_ADDRESS = &HF75

ERR_WORKFLOW_SEND_STATUS = &HF76

ERR_WORKFLOW_SEND_TASK = &HF77

ERR_WORKFLOW_DISPLAY = &HF74

ERR_WORKFLOW_CREATE_JOURNAL = &HF78


Revision History

Revision History (Both OEL and TeamWork™)

See also: Outlook Specific Functionality

Dec 12 2000 v2.5.x

New:
Help File! Full linked and indexed help (CHM) file. Approx 200 topics. Integrated with workflow designer
Field Validation New and improved field validation that does not one-off your forms
Task updating Private workflow tasks now track Public Folder tasks automatically! (Outlook 2000 only)
Item Sync Object Provides a method to automatically copy items to users' private folders
ItemProperties Allows a simplified way of accessing fields without one-offing your forms
UpdateLinks Update the contact links collection removing broken links and fixing the display names
GetItemFromURL Will return a item from a Outlook URL
GetFolderFromURL Will return a folder from a Outlook URL
SortArray Sorting arrays
MsgDataValidate Allows a combo box to validate the entry and automatically add it to the list through a dialog
CopyGridProperties A convenient function to copy grid control properties for help with printing
CurrentItem For external processes or earlier versions of Outlook to specify the current item
Replace For users of VBScript prior to version 5

ExitState More functionality Exit State can now be updated. No more "Do you want to save..." dialog

ArrayToText New NumColumns parameter and formatting in function
Examples Fragments of code you can use to add functionality to your forms

Improved:
GenRefID New sequence number capabilities
ExitState New Item_Close functionality... no more annoying "Do you want to save changes" dialogs
WriteToField New "AppendOnTop" parameter allow you to appended to the history log top down
Display GetItems.Display now has new delay parameter so it will work with opening up custom forms
ReadMsgEntryVar Now supports redirection to individual elements of a Grid (Keyword array)
ArrayToText Now support line wrapping columns
CreateObject Calling OEL from unmodified 1st page forms. (see: CurrentItem)
CalcDueDate Now convert time units to appropriate values. Ex: 4000 min will now say 3 days
PrintForm Print positioning for multi-line text box controls.
Tasks to yourself In earlier versions, you could not assign workflow tasks to yourself

CalcDueDate Improvement to display units formatting

Workflow Analyzer Various fixes, command line operation, plus a user reporting tool is included to get you started

Workflow Designer: better display of correct form fields; support for other new features added to TeamWork.

For all configuration items, the BillingInformation field is set to the last user who updated it.
PST support: Internet (non-Exchange) PST support for OEL.

Fixed:
O ne-Off forms Forms no longer one-off which means that your items are up to 100x smaller and run faster!
AddMsgSection Fixed message cache update error
OnLine Now can correctly report for non-English systems
AddMsgSection cache error
Icon link type setting in workflow Journal

Compatibility:

History.WriteToField aliased to History.Process (This is fully compatible... no changes necessary)

Two new REG keys: (Will default to nominal values if necessary)

Language

Public Folder Root

TeamWork workflow config keys:
(These will be automatically added by simply opening the config in the workflow designer and then saving it)

Notify Priority Set the importance of a task

Notify Reminder Set the pop-up reminder time of a task

OneOffSafe
ValidationColor

ValidationStyle

"IPM.Note.Workflow Task Request" needs to be republished .... new data format!

May 7 2000 v2.4.11

Fixed:
SetLock automatic recapture of Lock
TeamWork conditional branching for "<=", ">=" and "<>" cases
No default NextStep now clears next step list properly
Support.Timer function now works with custom fields
Checking instead of setting ListStyle and MultiSelect properties of workflow controls
Removed tool text tips from workflow controls. Allow them to be set in designer
Blank history field error is now properly trapped
Error in CalcDueDate when no event history was available
PrintForm control out-of-bounds testings

Added:

Support for using OEL with "Internet E-mail" as a service provider. (TeamWork is not supported however)
Navigate support for direct URL references while working off-line

OnLine property

TeamWork support for hiding and disabling individual tabs of a multi-page control
Workflow properties exposed: CurrentStep, DueDate & DueDateText
CheckLock function allows lock to be revoked without conflict
New agent scripting features. New agent "Events" object
New features in Demo Order Workflow form
Item config data redirection <<Subject, Section, Key>>

Compatibility:

@From and <Originator> fields change to ~~~Companies
Grid2.ocx and Cal2.ocx
REG key relocated

Added LinkType to Workflow Configuration file

Feb 21 2000 v2.3.5

Fixed:
Type mismatch error on ReadMsgSectionList and ReadMsgData functions has been fixed
PrintForm error hander and font underline
GetItem.Display now properly only displays the items pane in all versions of Outlook

Added:

Customized notification subject and text is now supported
Navigate now supports Outlook URL formatted path

DLLs can now be registered via a REG file

OutlookVersion property

Agent:

Check point log file

User registration system
Custom scripting support (partial)
Bridge error handling improved

Compatibility:

NotifySubject and NotifyText must be added to each step of a workflow

ReadMsgSection data array is now 0 based instead of 1 based

Nov 20 1999 v2.2.0

Fixed:
AddMsgSection now supports array variables as parameters

Added:

Step based automatic journal creation for workflow system

New "Support" object

· Timer function

· ClipboardText function

· FormatText function

· BeepTone function

· RunShell

Compatibility:

Add "JournalFolderURL=" and "JournalContactField=" to the workflow SetupInfo section

Add "JournalType=", "JournalSubject=" and "JournalText=" to each workflow step

NOTE: TextToArray and ArrayToText functions were moved to the new Support object.
"WriteMsgEntry" was renamed to "MsgEntry" to better match the property nature of the function.

Oct 21 1999 v2.1.11

Fixed:
Navigation error for more than one parent level up
Improved line wrapping functions in PrintForm
Potential false sub-string match of data keys in ReadMsgEntry
Notification DL acceptance processing

Added:

Per-step validation

Per-step hide and disable controls
Line-wrap switch and paper orientation selection in FormPrint function
Support for the Grid control in FormPrint

AddMsgSection and DeleteMsgSection functions
Agent notification for incorrect item message class
Improved agent error handling & configuration
Check list comments in event history

HomeFolder property

Compatibility:

Add "MessageClass=" to the workflow SetupInfo section

Add "HideControls=", "DisableControls=", and "ValidateFields=" to each step

Sep 20 1999 v2.0.3 - The Agent

Fixed:
Absolute date and forward step reference in due date calculation

OL2000 Categories error in History functions
Navigate function now can support "/" or "\"
Off-line form & navigation support

Added:

Agent DLL file (OlWfAgnt.DLL)

Agent lock notification option
CalcDueDate function exposed

Workflow Analyzer (Access MDE file)
Message Data Publisher (Access MDE file)

WatchDog monitor system

Web page status display

Compatibility:

LockNotify and MasterForm fields needs to be added to the SetupInfo section of each workflow.

Aug 24 1999 v1.8.9

Fixed:
Multi event update bug in client Lib.Workflow.Process function.
Line wrapping bug in PrintForm function.
Fixed GetPropertyValue for correct use in the PropertyChange event
Form exit library cleanup - close event code is no longer needed.
DL membership resolution issues have been addressed

Added:

Attachment tracking to history functions
Optional tracking of NotifyStatus in event history
OlCal.OCX calendar control
License property
WriteMsgEntry function

ReadMsgEntryVar function

SetFormSize and SetFormPos functions

Architecture separation of Client and Agent DLLs

Compatibility:
1) Add "TrackStatus=" to the Workflow Configuration [SetupInfo] section
2) OlGrid.OCX must be replaced and republished on all forms.
3) History.GetValue was changed to History.GetInitialValue
4) Remove the "c. n. k." prefixes from the history tracking field, they are no longer needed.
5) Remove all the code that is related to supporting library closure in the Item_Close event. It is no longer needed.
6) Add CryptoAccessResolved to the Workflow Configuration [SetupInfo] section
7) Add AuthorizedResolved and NotifyResolved to each step of each workflow
8) Add LastNotified to the Workflow Configuration [SetupInfo] section.

J uly 23 1999 v1.7.0

Added:
External (non Outlook script) library instantiation method established

Workflow analyzer built using external Library calls

ActiveTime parameter added so agent will avoid issuing alerts during off-hours.

Compatibility:
1) "ActiveTime=" needed in each Workflow Configuration message header to support new functionality.
2) "Workflow Holiday" message file must be added to each workflow configuration folder to support ActiveTime function.

July 1 1999 v1.6.0

Added:
Vector printing function.
Adjusting base Agent functionality .
Major speed improvement (10x) by adding cache function to all Configuration message read functions.
Added ' ^ ' OR checklist check.
Agent bridge function added

Compatibility:
1) Configuration message of each workflow changed from "WorkflowConfig" to "Workflow Configuration"
2) "StatusSubject=" key must be added to each step

June 1 1999 v1.5.0

Fixed fundamental multi-instance architecture limitation

May 9 1999 v1.4.0

First release for internal testing


Open Issues

There are some aspects and features of the Outlook Extensions Library and TeamWork that we have not had the opportunity to address fully at this point. Below are some issues that you should be aware of.

q International versions

We have not had the opportunity to test for potential language locality (Regional Settings) issues. Only the basic "English (United States)" setting has been used in testing, and thus we can only currently support with confidence this setting. We do not believe that supporting other locality settings will be a significant issue; we welcome the opportunity to test other settings. Please contact us if you wish to have a particular regional setting tested.

q Locking contention

The Workflow Agent needs to gain access to workflow items in order to properly record status information and to move items forward. If a user holds an item open for an extended period of time, the Agent is in effect unable to perform its job. This issue can be mitigated by various techniques. First, the Agent has some tools that will notify the user to save the changes (see the LockNotify field). Another approach for forms that have a potential for contention is to make the form come up in read-only mode by default. If the user needs to make a change, then use the Lib.SetLock function to obtain a lock. Careful design of the forms and workflow should minimize the potential impact of this issue. This issue should be solved in the next release with the use of revoking locks (CheckLock function) when necessary.

q Parallel item collection

The workflow system currently supports the ability to have one workflow item launch one or more parallel workflows (see the Bridge function). What is not yet provided is an ability to collect these workflow items and combine them back into a single item representation. Writing your own collector step using MAPI (CDO) is certainly a possibility that is not difficult if you are familiar with programming in Outlook and Exchange.

We intend to address this issue in two ways: (1) In the near future, we will provide some examples of how to use event scripting and of how to write your own collector process. (2) In future TeamWorkÔ releases, we will be providing some built-in (template-based) functionality that should meet most basic parallel workflow needs.


Agent Registration

The agent computer must be registered as a client computer as described in the previous license section. Additionally, the agent needs to have a user license message. This user license message exists as an item in the Workflow Agent public folder. It contains license information, including, for Agent mode licenses, information regarding the number of user licenses that your organization has purchased.

The number of users is defined by a 30-day sliding window. As each user (i.e. each distinct e-mail address) uses the agent, the person is logged into the “Agent User Data” message item, tagged with the current date. After 30 days of inactivity, the user is removed from this data file. If the e-mail address is deleted or is changed, it will be also be removed after 30 days. Do not attempt to modify this “Agent User Data” file because encrypted checksum values are constantly monitored. Any manual adjustment, or any attempt to copy the item, will result in the agent issuing a failure notice and then ceasing to operate.

Once you have purchased an Agent mode license, you will be sent a message with the subject “Workflow Agent License”. On receipt of the item, copy it to the agent folder and then press the “Set Key” button on the agent configuration screen. This “Set Key” process must be accomplished within 7 days from the date the agent registration was issued. If you miss this time period, contact TeamScope Software to obtain another license message item. Once the “Set Key” process has occurred, then you can discard the “Teamwork Agent License” item.


Workflow Tips

q Simple Advice

§ Start with the provided PST folder files and template file.

§ Set the library error-handling to display all errors (DisplayErrors=True).

§ Start with a simple form and build your way up.

§ Start with the Workflow Mode set to "User, Review, Test" to get the flow initially tested.

§ Start any new workflows added to the Agent by placing the workflow in "Mode=Agent, Review".

§ On the Agent mailbox, make sure to keep and check your Sent and Deleted items to monitor the activity.


Auto Selecting the Next Step

Sometimes you may want to use the features of the workflow system but maybe not force the user to use the TeamWork workflow controls. Because you have complete control over your Outlook form and controls and TeamWork simply uses Outlook controls you can select next steps and even check list items in the background programmatically. This is just a matter of accessing the workflow controls and selecting one or more items from the list.

Set oPage = Item.GetInspector.ModifiedFormPages("PageWithWorkflowControls")

Set oCtl = oPage.Controls("lstNextStep") ' reference the required Next Step control

oCtl.Selected(0) = True ' select the first step for example

Another variation is that you can actually have the workflow step through multiple steps without having to close and open the form.

oCtl.Selected(0) = True 'Select Next step in lstNextStep Control

oLib.Workflow.Process 'Update workflow event history, and proceed to the next step

oLib.Workflow.Setup 'Setup workflow form controls based on new step


Collecting Parallel Workflows

Sorry, please contact TeamScope for details.


End user reporting

Instructions:

The Workflow Analyzer comes as part of the TeamWork agent mode license. You are required to purchase this license before you can use this feature.

Outlook Setup:

1) Setup a standard client computer with MS Office installed (requires Outlook and Access) with the library DLL installed (OlExtend.DLL)

2) Copy the Workflow Analyzer (Workflow Analyzer 97.MDE or Workflow Analyzer 2K.MDE depending on your version of MS Access) to a folder on this computer.

Workflow Agent Configuration:

3) The Workflow Analyzer requires an agent "Workflow Agent Configuration" file to be present.

If you are not actually using the Agent you can manually setup a configuration item to operate in its place. The format of this message is shown below however; only two key lines (shown in bold below) are required to have the Workflow analyzer operate. The important part is that depending on the location of this item you need to perform folder navigation to the target workflows configuration folder. See the libraries Navigate function for more details on specifying a relative folder path. You can place this item directly in the workflow folder and then leave the ConfigLocation="" if you are only interested in the current workflow.

[SetupInfo]

Owner=User E

PollInterval= 60 sec.

LoadAlert= 105 %

LoadWarn= 45 %

LogActions= 1

SendWFErrors= 1

SendAgentErrors= 1

StatusWebPage=

[** InBox Response **]

ConfigLocation=<InBox>

CountDown= 1 min.

RunScript=0

Maintenance= 5 min.

[The Name of your workflow]

ConfigLocation=..Path to wf config (see Navigate)

CountDown= 5 min.

RunScript=0

Maintenance= 2 hrs.

Running the Workflow Analyzer:

4) Once this configuration item has been published to a folder or you already have active Agent based workflows you are ready to start the Workflow Analyzer. You will need to close any active Outlook items before you can use the Workflow Analyzer.

Have Outlook pointing at (selecting) the "Agent Workflow Configuration" and press the "Set" button. This should display the folder path to the item.

5) Next press the "Connect" button. If the Agent Workflow Configuration item is correct it should show the name of the workflow in the list of Workflows. To check that the correct workflow is selected you can press the "Open Folder…" button. This button should open the workflow data folder.

6) Select the "Include Field Data" if you want to collect the data from your form and set the date filter to the date range that you are interested in extracting. Select the workflow from the list that you want to extract data from and press the "Export" button. This button should start the data transfer to Access. If there are any errors or issues you will be notified.

Note that you only need to run the Workflow Analyzer as needed. Typically you may want to run it once a day at midnight to avoid any disruption on your network during the day. Unfortunately the Workflow Analyzer at this time cannot be run from the command line without using some form of keyboard macro utility.

Making your own reports:

The Workflow Analyzer itself is a "fixed" version of Access meaning that you cannot add or modify any forms or reports in it directly. If you want to add your own reports for instance you can do this by creating your own Access MDB database file and connecting this to the data in the Workflow Analyzer. To facilitate this we have provided a "Workflow Reporting Tool.MDB" file, which you can modify and add, any reports that are specific to your company as needed. This separation of the Workflow Analyzer and your custom MDB also has advantages because if the Workflow Analyzer undergoes any changes it will not affect your own file.

Linking tables:

A form called "Setup Links to Workflow Analyzer" is provided in this MDB file that will automatically connect the necessary linked tables. You only need to run this once to link the two systems or to reconnect if you move the Workflow Analyzer database file.

7) Delete the following linked tables in the MDB file if they exist:
"Item", "ItemData", "ItemEvents" and "Template"

8) In the "Setup Links to Workflow Analyzer" form enter the full file path to the Workflow Analyzer. Then press the "Set Links" button. If this is successful then you should now have 4 new linked tables as described above.

Writing Reports:

From this point on it is just 100% standard MS Access. Persons familiar with the basics of writing reports in Access should not have any difficulties. What is important to understand is the relationship between the 4 tables and how they represent the data in your workflow. The entity relationship diagram is shown in the Workflow Analyzer. To properly extract this data properly you must make use of cross tab queries. We have provided a query called "Item Data CrossTab" that does this for you. You can use this query or your own as a basis for your reports. We have also provided a simple user form called "Workflow Reports" that you can use as a starting point form. This form has some already built in feature that may make getting started quicker. For instance, reports that are added to the database will automatically show up in the form.

Linking to the Outlook Toolbar:

Being able to launch your MDB workflow reports from the users Outlook toolbar completes the process. Versions of Outlook before 2000 require special MAPI tools to add anything to the Outlook toolbar. With Outlook 2000 you may want to consider using COM add-ins that offer many other benefits. The method presented while limited will work with all versions of Outlook.

Install the DLLs
Copy the TSBTN1.DLL file and TSICONS.DLL to the clients windows system directory

Register the extension:

Run (dbl-click) the BtnExch.REG file as shown below.
This registers an Exchange client extension to point to the DLL

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions]

"Workflow Analyzer"="4.0;TSBTN1.DLL;1;010001;1000000"

Define behavior:

The TSBTN1.DLL file is "hard coded" to look into a specific registry location to define the behavior of the toolbar DLL. The Button1.REG file is shown below. Make sure to adjust the "ShellExecute" key to correctly point to your MDB file. You can also adjust the "MenuText" and "ToopTipText" keys but do not change any of the other entries.

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\TeamScope\OEL\OutlookExtension]

[HKEY_LOCAL_MACHINE\SOFTWARE\TeamScope\OEL\OutlookExtension\TSBTN1.DLL]

"CustomFormName"=""

"Formlaunch"=dword:00000000

"IconIndex"=dword:00000059

"MenuText"="Workflow Analyzer"

"ShellExecute"="D:\\Tools\\Analyzer\\Workflow Reporting Tools.mdb"

"ToolTipText"="Run TeamWork workflow reports"

Register the behaviour:

Save the new Button1.REG file and run it on the client's computer to register the buttons behavior.

You can repeat the process above to add more buttons by copying and changing the name of the DLL.


Form letters

This example demonstrates a simple use of the variable redirection capability. This capability has a number of advantages over hard-coding them into your forms.

  • Easy to make adjustments without having to republish forms

  • Smaller form size

Sub cmdCreateMail_Click

Set MyItem = Application.CreateItem(0)

MyItem.Subject=Item.UserProperties("Project")

MyItem.Body=oLib.Config.ReadMsgEntryVar("Form Letters", "Easter", "Hello", Item)

MyItem.Display

End Sub


Launching Parallel Workflows

Sorry, please contact TeamScope for details.


Undo Next Step Selection

If the user has selected a step but then changes their mind and wants to undo the step selection. On the Template and Demo forms there is a thin command button below the Next Step selection list that will run the simple code below.

Sub cmdUndoNextStep_Click() ' thin button below the Next Step box; allows you to unselect the step

tWFPage = oLib.Config.ReadMsgEntry("Workflow Configuration","SetupInfo","FormPage")

Set oPage = Item.GetInspector.ModifiedFormPages(tWFPage)

Set oControl = oPage.Controls("lstNextStep")

For i = 0 To oControl.ListCount - 1

oControl.Selected(i) = False

Next

End Sub


Data Publisher

Message Data Publisher Utility

For those using the Extensions Library's Config message data functionality, the Library includes a tool that allows you to easily keep your data items updated from an external database. The Message Data Publisher provides a very simple, yet very powerful, turnkey solution to publishing ODBC data to Exchange Public Folder data messages. These message data items are in the same efficient "INI" format that can be used by the all of the functions in the Outlook Extensions Library's Config object. When the Publish process is run, any changes in the ODBC data will automatically cause the corresponding message item to be updated.

Set Folder Path Button
Select the desired target folder in Outlook, then press this button. It will automatically place the correct folder path in the field.

Open Folder Button
Opens the specified Outlook folder.

Query Subject Combo Box
Lists each of the available queries that define the field mapping. Details on how to define the queries are provided below.

Open Query Table Button
Displays the selected query.

Open Message Item Button
Opens the specified message item with the matching subject in the folder.

Update Message Item Button
Performs the message data item update. It does not update the message item unless the item has actually changed. This is important in keeping static tables from causing unnecessary network traffic. If the "Update Check" option is selected and the item needs to be updated, a message dialog will appear if any changes are necessary.

Last Checked
The date and time when he last check was performed.

Last Updated
The date and time when the message item was actually last updated because of a change in data.

Size
Displays the size of the message.

Data mapping

To use the Publisher, you create a mapping between an ODBC data source and a message data item. Using the MS Access table linking and query designer capabilities, you can map from virtually any data source. The key to the Publishers operation is in how you set up the queries in Access. For the first level of mapping, the name of the query must match the name of the message in the folder. The second level of mapping is defined by the number of columns specified in the query:

1 Column
If the query has only one column, then the resulting message contains one single list with no sections (this data format can be used by the ReadMsgData function where a blank section is specified).

2 Columns
If the query has two columns, then the resulting message contains sections, as defined by the first data column, and values within that section, defined by the second column (this data format can be used by the ReadMsgData function where the section is specified).

3 Columns (or more)
A query with three or more columns is defined identically to the two-column query above; in addition, each of the following columns are included as values on the field entry line with a ";" as a delimiter (the resulting data format can be used by the ReadMsgEntry or ReadMsgEntryVar function with a section and field specified).

Publisher
Once you have set up the mappings on all of your data sources, you can then run them automatically all at once using the Publisher. The Publisher form simply cycles through all of the data map entries and records the results to a log file.

Your can have this form run automatically and then exit Access by specifying a "/x AutoRun" command-line parameter when starting the Message Publisher.mdb file. This command switch allows the updates to be automatically run periodically by a command-line timer such as Win AT.

Example:

"C:\Program Files\Microsoft Office\Office\MsAccess.exe" "c:\MyFolder\Message Publisher ??.mde" /x AutoRun


Status Notify

Workflow status notification

Any step in the workflow can respond automatically via a simple text e-mail message to both internal and/or external recipients. This is accomplished in the workflow designer in the Status Notification dialog. (See Status Notification concepts for more information) Because the StatusText field can be combined with text and one or more fields, basically any text response is possible with little effort. Understanding field redirection is important to taking full advantage of this basic but powerful feature.

StatusNotify= Address | <originator>

StatusSubject= Subject line text

StatusText= Text being sent (including field redirection)

Example Template:

… Other step keywords …

StatusNotify= <originator>

StatusSubject= {{Subject}} order request

StatusText= We have received you workflow request {{Subject}} for {{Vendor}}. <cr><cr> You will be notified when the order has been approved. <cr><cr> Thank you.


Workflow Analyzer

TeamWorkÔ ‘s Workflow Analyzer provides a turnkey tool for exporting data from your workflows, and provides for some built-in analysis of workflow statistics. The workflow analyzer comes as part of the TeamWork™ agent system. The workflow analyzer is provided in either the "Workflow Analyzer 97.mde" or "Workflow Analyzer 2k.mde" depending on the version of Access you are running. You can use the tool to provide powerful reporting capabilities to you users via MS Access.

Features of the Workflow Analyzer:

· MS Access (MDE)

· Easy-to-use GUI interface (see below)

· Error logging

· Automatic exporting of all data from a workflow to a standard ODBC database

- All workflow items

- All event history

- All change history-tracked fields

· Provides expert analysis of workflow trends

Planned (configuration) vs. Actual (event) durations

Most-traveled workflow paths

Activity (events) Per Hour graph

Operational Notes

Agent Folder Path..> Set:

Select the folder where the workflow agent configuration file is located. This should be in the same folder as the actual workflow agent form. Open Outlook to this folder and then press the "Set" button.

Connect:

This button connects scans the defined workflows and lists them in the "Workflows:" list window. Select the workflow you want to export.

Open Folder:

This just provides a shortcut to the selected workflow folder to test the setup links.

Include Field Data:

Selecting this option will look a the workflows Change History field listing and extract the data form these fields. For normal operation you will always want this option.

Last Run:

Displays the name of the workflow and time it was last extracted

Date Filter:

Allows you export a portion of the folders data based on either the date the item was created or the date the item was last modified.

Command line

The workflow analyzer can be run from the command line. Before it can be run from the command line it must first have its Agent Folder Path set. The line below is the format of the necessary command line. Make sure to adjust the locations and names to match your files.

"C:\Program Files\Microsoft Office\Office\MsAccess.exe" "c:\MyFolder\Workflow Analyzer ??.mde" /x AutoRun /cmd "name of workflow [; From Date][; To Date][; Created | Modified]"

The only part of this command line that can be adjusted is the command string after the "/cmd"

Name of Workflow: The name of the workflow as displayed in the analyzer which you want to export data from

From Date: Optional Date to start exporting records (Default is 1/1/1900)

To Date: Optional Date to stop exporting records (Default is 1/1/2900)

Created | Modified: Optional Specify whether you want the date filter to be applied to the date the items were created (Created) or the date the items were last modified (Modified). The default is Created

Workflow Analyzer - Access Database Table layout diagram

The output from the is stored in the workflow analyzer in local predefined Access tables. This data is displayed in the "Data" page of the workflow analyzer as shown below.

Below is the description of the tables and relationships that are defined by the workflow analyzer.

ConfigData- Stores setup and configuration information

Debug 1= use interactive debugging, 0=only log resulting errors

Delimiter Specify what delimiter you want for field array data

Last Run Date Date and time that the last export was run

Last Run Name Name of the last workflow that was exported

Minimum Version Check to make sure you are running with the correct Library version

WF Agent Path Path to the Agent workflow folder. This can be set automatically by pressing the "Set" button after you have opened the Agent folder in Outlook.

ErrorLog - Records any errors that may have occurred

(An error message dialog will pop up if any errors occurred during export)

Error Internal (VB) error message

Description Process in which the error occurred

DateTime The date and time when the error occurred during the export process

Item The message item that generated the error

Type Warning=some data may be missing; Fatal=all data exported is suspect

Item - Each workflow message item

FirstCreated The date-time when the item was created

LastModified The date-time when the item was last modified

Creator The address of the mailbox that created the posting (via CDO)

Originator The originator as returned by the Lib.Originator property

Size The size of the item, including attachments

Attachments The count of the number of attachments

Subject The item’s subject

Body The text from the item’s body

EntryID The unique MAPI GUID of the item

Categories The standard Outlook Categories field with ',' value separators

ItemData - All fields that are being tracked by the "HistoryFields" parameters

(Note: Data can be displayed as columns by using a crosstab query)

Name The name of the field

Value The value of the named field (255 characters max)

ValueMemo If the field value is longer than 255 characters, then it is stored here also

ItemEvents - The event history array data for each item

Step The step name as defined in the workflow configuration

Who The name of the person (mailbox) that preformed the step-event

Event The actual event that occurred

When The date and time that the event occurred (the “actual”)

Planned For each “Complete#” step, the calculated planned due date/time is stored

Template - The workflow configuration; used to hold baseline information for analysis

Name The name of the workflow step

Duration The duration of the step - defaulted to minutes

Writing reports

Because the workflow analyzer is a Access MDE file it cannot be modified which means that you cannot add any forms or reports. However, you can link to this database with your own Access database and do anything you please. To get you started we have provided a MDB file (WFA end user.mdb) which has a simple form that you can run that will link up the database with the workflow analyzer. .. see example.


Workflow Bridge

Input Posting: Starting a workflow

The Workflow Bridge function accepts a simple text message and, based on the contents of the body of the message, synthesizes a new full MAPI (Outlook) message. This function allows for non-MAPI capable systems to in effect post a Outlook (MAPI) message to any Public Folder, which means that an external process can start a workflow instance.

The format of an in-bound message to post to a Public Folder is:

To: Your Workflow Agent Mailbox address

Subject: Workflow Bridge

Body: ("fields" each on a separate line as defined below)

Special required fields:

@FolderPath= Relative or absolute path to folder. ex: ..\Folder\TargetFolder\
(See the Outlook Extensions Library’s Navigate function for format details)

@MessageClass= Message Class of item in folder ex: IPM.Task.Order Processing

@From= (Optional) Specifies the actual sender’s name.
Used by the Originator function. Be sure to use a resolvable address in order for the Originator function to function properly.

Built-in Fields:

For any given base message class, certain fields are predefined or built-in. These fields must be identified by preceding them with a ' * '. Here are some common built-in fields:

*Subject= It is important to make sure this entry will be unique in the folder

(See the Outlook Extensions Library’s GenRefID function for more information)

*Body= ^First Line of Text | Second Line of Text | … (see field codes below)

*Categories= Category1, Category 2, Category 3
(Note: The built-in Categories field is actually a Keywords array data type field in which Outlook automatically uses ',' or ';' to separate the array elements.)

Field values codes:

To force a custom field to be of a certain data type when generating the new message, you must use a special preceding character. Built-in fields do not need to specify any type because the type is already defined; however, if you wish to use the multi-valued fields with ' | ' you must specify the type.

Code: Outlook Type:

! olYesNo

# olDateTime

% olNumber

$ olCurrency

& olKeywords … Multi-value array with values separated by ' | '

^ olText … Multi-line text with ' | ' as the line <CrLf> delimiter

(none) olText

Workflow required fields:

Important: The two workflow fields "StatusField=" and "EventField=", as defined in the workflow configuration message, are required for any workflow-enabled posting. The fields can be blank, but must be defined regardless. The "EventField" must be defined as a Keywords field type, as shown below.

Status=

Events=&

where "Status" and "Events" are the names of the "StatusField=" and "EventField=" in the target workflow folder.

If you place data into these fields, be careful because the values of these fields must have a correlation with the operation of the target workflow. Faulty data in these two fields will likely cause this workflow item to generate an exception, and could potentially impact other workflow items as well.

Note that if the target workflow performs field level validation, the Bridge message must contain a reference to each field that has validation assigned regardless of the step. The value for the field does not have to contain a valid value but must simply be specified. The Bridge function does not perform validation in this current product release.

Example Bridge Input:

To: WorkflowAgent@YourCompany.com

Subject: Workflow Bridge

Body: @FolderPath=..\Workflows\Vendor Approval

@MessageClass=IPM.Task.Vendor Approval

@From=Sally.Smith@Vendor.com

*Subject=PO12AB87

*DueDate=Dec 20 2001

*Body=^Please review|| Address: 1234 Olive Branch | Orange, CA 98765

Vendor=Big Joe Hardware

License Cost=$1500

Workflow Status=

Event Status=&0: Internal Review|Sally Smith|Vendor OK|8/22/99

Important Technical notes

Because the Workflow Agent is actually the mailbox that created the MAPI message, standard MAPI properties will show the sender of the message as the Workflow Agent. To overcome this issue, you can use the library's special Originator property to return the true message originator.

The Workflow Agent must be configured and running for the Bridge function to be operational. The Workflow Agent mailbox must have "Owner" rights to the target folder. The target folder does not have to be a workflow-related folder; the Bridge function is generic and can post any item to any folder to which it has the proper permissions.

If the Bridge message fails, a copy of the body of the original incoming e-mail message will remain in the Agent folder with the subject "Bridge Temp Store". You can use this copy to review the cause of the failure, make adjustments, and resubmit if appropriate.

Warning

Keep in mind that messages from external systems cannot be authenticated because of the nature of SMTP and the Internet. Any external organization can post items to an internal workflow if they know the address of the Agent mailbox and a valid folder path. You can use Exchange’s administrator tools to limit delivery to the Agent if you want an additional level of protection.


Authorized

Flag to indicate whether the form user is authorized for this step of the workflow. Use this flag to disable controls or events in your script as appropriate.

Flag = oLib.Workflow.Authorized

Call during: After initial workflow Setup

Notes:
If this function returns a unauthorized indication (Authorized=False) then it will automatically disable the workflow controls on the Outlook form. Although this does not automatically set the ExitState property as do some other functions you can use Authorized to set it to cancel the Item_Write event if you want.

The Authorized list is set in the workflow designer in the "Authorized List" dialog. The data is stored in the Authorized and AuthorizedResolved keys in the workflow configuration item.


CalcDueDate

The Panned due date

Date on which a step is scheduled to be due, based on the parameters defined in the workflow configuration. See time and duration for more information

Date = oLib.Workflow.CalcDueDate (Step, Item, [EventFieldName], [DisplayReturn])

Call during: Any time after Setup

Date: The date and time at which the step of the Item is due, according to the workflow configuration

Step: The name of the step as defined in the workflow configuration. Typically this step is the current (pending) step, but can be any previous step.

Item: (Object) The Outlook Item object.

EventFieldName: (Optional) The name of the event field. You only need to specify this parameter if you are calling the function from outside of a workflow form where the Setup function has not been called first.

DisplayReturn: (Optional) A user-friendly status return which includes the number of days/hrs/mins that the item is due or overdue by. This is the same value that is normally displayed in the workflow form’s "txtDueDate" field.

Notes:

This method is used internally to determine an item’s expected (planned) due date. This planned due date is determined by the step’s Duration field and the event history of the item. The value determined by the CalcDueDate method is dependent on many factors.

This function is only necessary if you are interested in determining what the planned date for a step was. The Workflow Analyzer uses this function and provides this data in the Item Event field for each complete step. The current values for this function in a workflow are available directly as either the DueDate or DueDateText properties.

The returned Date time units will convert up based on these break points:

  • If min. > 120 Then convert to hrs.

  • If hrs. > 48 Then convert to days


Current Step

These properties allow for easy access to the data displayed in the workflow controls. These properties are only valid after calling the Workflow.Setup function.

Text = oLib.Workflow.CurrentStep

Text: The name of current step


DisplayCurrentStatus

View the current workflow status: (optional)

oLib.Workflow.DisplayCurrentStatus [ColumnWidths]

Call during: User command button click event after the initial Setup has been called

ColumnWidths: (Optional) olGrid ColWidth parameter Default="1700,2400,1305,425" units are TWIPS

Note:
All steps are shown. If a step has completed on (or ahead of) time, then it is marked green. Steps that completed late are marked in red. The current step is marked in yellow. Requires the OlGrid control.

See: Workflow Form Controls; DisplayEventHistory


DisplayEventHistory

Display Event History & Status: (Optional)

oLib.Workflow.DisplayEventHistory [ColumnWidths][,AppendOnTop]

Call during: User command button click event after the initial workflow Setup has been called

ColumnWidths: (Optional) olGird ColWidth parameter Default="1700,2400,1305,425" units are TWIPS

AppendOnTop: (Optional - Boolean) True: Append latest changes to top of display. Default=True

Note:
History is shown starting with the most recent. Requires the OlGrid control.

See: Workflow Form Controls; DisplayCurrentStatus


Due Date

These properties allow for easy access to the data displayed in the workflow controls. These properties are only valid after calling the Workflow.Setup function.

Date = oLib.Workflow.DueDate

Date: The date value that is displayed in the due date textbox

See: CalcDueDate


DueDateText

These properties allow for easy access to the data displayed in the workflow controls. These properties are only valid after calling the Workflow.Setup function.

Text = oLib.Workflow.DueDateText

Text: The full text of the Due Date field including the date
Example: [Over due by 3 days] Apr 3 2000

See: CalcDueDate


Originator

A property which returns the visible address of the originator of the workflow item. This property is very useful because a workflow item may come from the workflow Agent or from other processes, and using the native Outlook sender properties will not provide the desired results.

Text = oLib.Workflow.Originator([Item])

Call during: After Lib.Workflow.Setup

Item: (Optional; Default=Current Item) Item to use to determine original sender

Text: E-mail address display string

Notes:

The Originator function uses a prioritized approach to determining who the originator should be:

1) Companies field with "~~~" appended at the beginning
2) First entry in event history
3) Else the CurrentUser.

For normal operation, the first person (CurrentUser) who starts a workflow item and saves will be marked as the originator. Only when an intermediate process such as a gateway for agent function (Bridge) should you need to preset the Companies field with the real originator. When manually presetting the Companies field you need to proceed it with "~~~"

Although the Companies field cannot be set or viewed normally from the Outlook UI, it can be set by any MAPI or Outlook process. Because of this, one could potentially attempt to "spoof" the originator by posting an item with a misleading or incorrect address. This would not be ultimately successful, however, because MAPI does internally store who actually generated the posting, which value cannot be spoofed. You can use the Workflow Analyzer to run a report of which mailboxes posted on behalf of which addresses.


Process

Process the workflow for the current item and progress the workflow to the next step if appropriate

oLib.Workflow.Process

Call during: Item_Write

Sets: ExitState: Increments the value of ExitState by one if any workflow-related processing was completed by the user.

See: Setup

Note:
This routine does not actually save the values in Outlook. You must allow the form to complete the normal Outlook Item_Write event, which will actually store the message.


Setup

Set up the workflow process and user interface controls for display.

oLib.Workflow.Setup [Display]

Call during: Item_Open

Display: (Optional; Default=”History”) "History", "Status", "None" Display event history or workflow status along with required base workflow controls. If you are not using the workflow display grid control, you can improve the speed of loading the workflow by setting the value of Display to "None".

Note:
You can call this method from multiple routines within your item’s script code, and there is no problem with calling it more than once within the processing of the item. Calling the method again after the Item_Open can be valuable if you want to update the workflow display. If in the handling of the item the user can change data that impacts any aspect of the workflow, you should call this function again. If a step makes use of the “conditional step” feature, make sure to call this method whenever the field referenced by the next step CaseField is changed.

The Setup method will, by design, always "dirty" the Outlook form and thus cause an Item_Write event to occur. This is done to insure that even for unbound controls, such as the checklist, that the workflow’s Process method is always called in the Item_Write event.


OEL Workflow Foundation

TeamWork™ Workflow

The Outlook Extensions Library provides the foundation for the TeamWork™ workflow product. The because of this close relationship, the functions for operating the workflow system are included in the same OlExtend.DLL file. The TeamWork product is optional and must be registered if you use any of the workflow functions. Note that the TeamWork product by definition includes the Outlook Extensions Library.

To understand how the workflow system works you need to review the information that is included in the TeamWork™ product.

Library call interface

The calls interface into the workflow system are simple for the most part because most of the behavior of the workflow system is defined by the workflow configuration file which in turn is controlled by the workflow designer. To access properties of the workflow template you can use the set of configuration data functions provided with OEL.

Below is a list of the library functions that can be called from VB Script to operate with your form:

Primary required workflow calls

Setup Setup the workflow in the Item_Open event

Process Process the users inputs in the Item_Write event

Workflow display controls

DisplayEventHistory

DisplayCurrentStatus

Step based functions

Authorized For a given step determine if the current user is authorized

CalcDueDate For a given step determine its due date

Form data access

DueDate Read the value of the Due Date

DueDateText Read the text of the Due Date message

CurrentStep Read the name of the current step